首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >2026-07-01:找出最小平衡下标。用go语言,给你一个整数数组 nums。我们要找“平衡下标”里最小的那个下标 i。 对任意下标 i,把数组分成

2026-07-01:找出最小平衡下标。用go语言,给你一个整数数组 nums。我们要找“平衡下标”里最小的那个下标 i。 对任意下标 i,把数组分成

作者头像
福大大架构师每日一题
发布2026-07-01 20:46:24
发布2026-07-01 20:46:24
30
举报

2026-07-01:找出最小平衡下标。用go语言,给你一个整数数组 nums。我们要找“平衡下标”里最小的那个下标 i。

对任意下标 i,把数组分成左右两部分:

  • • i 左边的所有元素求和,记为 leftSum(如果左边没有元素,那么 leftSum = 0)。
  • • i 右边的所有元素求乘积,记为 rightProd(如果右边没有元素,那么 rightProd = 1)。

如果满足 leftSum == rightProd,则这个 i 就称为“平衡下标”。

最后返回所有满足条件的下标中最小的那个;如果一个都找不到,返回 -1。

1 <= nums.length <= 100000。

1 <= nums[i] <= 1000000000。

输入: nums = [2,1,2]。

输出: 1。

解释:

对于下标 i = 1:

左侧总和 = nums[0] = 2

右侧乘积 = nums[2] = 2

由于左侧总和等于右侧乘积,下标 1 是平衡下标。

没有更小的下标满足条件,因此答案是 1。

题目来自力扣3862。

一、分步详细执行流程

数组长度=3,初始状态: sum=0,mul=1,l=0,r=2 循环条件:l < r,只要左右指针没相遇就持续迭代。

第1轮循环:l=0,r=2,l<r成立

比较 sum(0)mul(1)0 < 1,走左侧累加分支

  1. 1. 将 nums[l]=nums[0]=2 加到 sum:sum = 0 + 2 = 2
  2. 2. 左指针右移:l = 0 + 1 = 1 本轮结束状态:sum=2,mul=1,l=1,r=2

第2轮循环:l=1,r=2,l<r成立

比较 sum(2)mul(1)2 > 1,走右侧累乘分支

  1. 1. 溢出预判:检查 mul * nums[r] 是否超 1e14。当前 mul=1,nums[r]=nums[2]=2,1*2=2 < 1e14,无溢出风险
  2. 2. 右侧乘积更新:mul = 1 * 2 = 2
  3. 3. 右指针左移:r = 2 - 1 = 1 本轮结束状态:sum=2,mul=2,l=1,r=1

循环终止判断

此时 l=1、r=1,l < r 条件不成立,跳出循环。

循环后校验平衡条件

判断 sum == mul:2 == 2,条件成立,返回当前 l 值 1,和题目输出一致。

二、通用场景完整逻辑拆解(不局限示例)

步骤1:初始化变量

  1. 1. 求和变量 sum 初始为0:代表分割点左侧无元素时的初始和;
  2. 2. 乘积变量 mul 初始为1:代表分割点右侧无元素时的初始乘积;
  3. 3. 左指针 l 从数组最左端0开始;
  4. 4. 右指针 r 从数组最后一个下标 len(nums)-1 开始。

步骤2:双指针收缩主循环(l < r 持续执行)

每次循环分两种分支判断:

分支A:sum < mul,扩充左侧区间

说明当前分割点偏右,需要把左边下一个元素纳入左侧求和区间:

  1. 1. 左指针指向的元素 nums[l] 累加进 sum;
  2. 2. 左指针 l 向右移动一位,代表候选平衡下标右移一位。

分支B:sum ≥ mul,缩减右侧区间

说明当前分割点偏左,需要把右边下一个元素纳入右侧求积区间:

  1. 1. 溢出校验:判断 mul > 1e14 / nums[r]。若成立,代表 mul * nums[r] 会超出设定上限,乘积会无限变大不可能和有限的sum相等,直接返回-1结束程序;
  2. 2. 无溢出则将 nums[r] 乘入 mul;
  3. 3. 右指针 r 向左移动一位。

循环终止条件

l 和 r 指针重合时停止循环,此时重合位置 l 就是唯一候选平衡下标。 原理:双指针不断收拢区间,最终重合点恰好对应:左边全部是 [0, l-1](累加和sum)、右边全部是 [l+1, end](累乘积mul),完美匹配平衡下标i=l的左右计算规则。

步骤3:循环结束后校验平衡条件

  1. 1. 若 sum(i=l左侧总和)等于 mul(i=l右侧乘积),说明 l 是合法平衡下标,直接返回 l;
  2. 2. 若两者不相等,不存在任何平衡下标,返回 -1。

特殊兜底逻辑说明

当右侧累乘即将溢出 1e14 时直接返回-1: 数组元素最小为1,一旦乘积突破1e14,后续只会越乘越大,而左侧求和是线性增长、增速远慢于乘积,二者永远无法相等,提前剪枝避免无效循环与数值溢出崩溃。

三、时间复杂度分析

整个算法只有一层 while 循环,左指针 l 只向右移动、右指针 r 只向左移动,两个指针合计最多遍历数组全部元素一次,每个元素只会被 l 或 r 访问恰好1次。 数组长度记为 n(1 ≤ n ≤ 1e5):

  • • 总操作次数 ≤ n
  • • 时间复杂度:O(n)

四、额外空间复杂度分析

算法仅定义固定数量临时变量:sum、mul、l、r,没有开辟任何随数组长度n变化的数组、切片、哈希表等存储空间,额外空间与输入规模无关。

  • • 额外空间复杂度:O(1)(常数级空间)

Go完整代码如下:

.

代码语言:javascript
复制
package main

import (
    "fmt"
)

func smallestBalancedIndex(nums []int)int {
    sum, mul := 0, 1
    l, r := 0, len(nums)-1
    for l < r {
        if sum < mul {
            sum += nums[l]
            l++
        } else {
            if mul > 1e14/nums[r] {
                return-1
            }
            mul *= nums[r]
            r--
        }
    }
    if sum == mul {
        return l
    }
    return-1
}

func main() {
    nums := []int{2, 1, 2}
    result := smallestBalancedIndex(nums)
    fmt.Println(result)
}
在这里插入图片描述
在这里插入图片描述

Python完整代码如下:

.

代码语言:javascript
复制
# -*-coding:utf-8-*-

from typing import List

def smallest_balanced_index(nums: List[int]) -> int:
    sum_val = 0
    mul_val = 1
    l, r = 0, len(nums) - 1
    
    while l < r:
        if sum_val < mul_val:
            sum_val += nums[l]
            l += 1
        else:
            # 检查乘法是否会溢出
            if mul_val > 10**14// nums[r]:
                return-1
            mul_val *= nums[r]
            r -= 1
    
    if sum_val == mul_val:
        return l
    return-1


if __name__ == "__main__":
    nums = [2, 1, 2]
    result = smallest_balanced_index(nums)
    print(result)
在这里插入图片描述
在这里插入图片描述

C++完整代码如下:

.

代码语言:javascript
复制
#include <iostream>
#include <vector>
using namespace std;

int smallestBalancedIndex(vector<int>& nums) {
    long long sum = 0;
    long long mul = 1;
    int l = 0, r = nums.size() - 1;

    while (l < r) {
        if (sum < mul) {
            sum += nums[l];
            l++;
        } else {
            // 检查乘法是否会溢出
            if (mul > 100000000000000LL / nums[r]) {
                return-1;
            }
            mul *= nums[r];
            r--;
        }
    }

    if (sum == mul) {
        return l;
    }
    return-1;
}

int main() {
    vector<int> nums = {2, 1, 2};
    int result = smallestBalancedIndex(nums);
    cout << result << endl;
    return0;
}
在这里插入图片描述
在这里插入图片描述

·


我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。

·

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-06-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 福大大架构师每日一题 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、分步详细执行流程
    • 第1轮循环:l=0,r=2,l<r成立
    • 第2轮循环:l=1,r=2,l<r成立
    • 循环终止判断
    • 循环后校验平衡条件
  • 二、通用场景完整逻辑拆解(不局限示例)
    • 步骤1:初始化变量
    • 步骤2:双指针收缩主循环(l < r 持续执行)
      • 分支A:sum < mul,扩充左侧区间
      • 分支B:sum ≥ mul,缩减右侧区间
      • 循环终止条件
    • 步骤3:循环结束后校验平衡条件
    • 特殊兜底逻辑说明
  • 三、时间复杂度分析
  • 四、额外空间复杂度分析
  • Go完整代码如下:
  • Python完整代码如下:
  • C++完整代码如下:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档