← 返回题目列表

寻找数组中心下标为什么适合用前缀和思维?

简单 第 17 / 20 题 更新于 2026/07/31
前缀和数组边界

简化版

中心下标要求左侧元素和等于右侧元素和。

先求数组总和 total,遍历时维护左侧和 leftSum,右侧和可以由 total - leftSum - nums[i] 得到。

如果两边相等,当前下标就是中心下标;遍历结束没有命中就返回 -1

详细版

这题不一定要真的建完整前缀和数组,因为每个位置只需要左侧和。

遍历数组前先计算总和。来到下标 i 时:

rightSum = total - leftSum - nums[i]

如果 leftSum === rightSum,说明 i 左右两边平衡。判断结束后,再把 nums[i] 加入 leftSum,供下一个位置使用。

注意中心下标左侧或右侧可以为空,空区间和按 0 处理。

时间复杂度 O(n),空间复杂度 O(1)

完整版教学

一、题目真正考的平衡关系

中心下标的定义是:某个位置左边所有元素之和等于右边所有元素之和。它不是找数组中间位置,也不是找值最大的点,而是找一个“分割点”。一旦把题目看成分割点,两侧区间和就自然引出前缀和思维。

记忆钩子:中心下标不是几何中心,而是左右区间和的天平平衡点。

二、为什么只需要 total 和 leftSum

如果完整前缀和为 prefix[i],左侧和是 prefix[i],右侧和是 total - prefix[i + 1]。但遍历时我们可以直接维护当前位置左侧和 leftSum,不必额外开数组。当前位置右侧和由总和减去左侧和再减去当前值即可。

变量含义更新时机
total全数组总和遍历前一次性计算
leftSum当前下标左侧元素和判断当前下标后更新
rightSum当前下标右侧元素和每轮临时计算

这就是前缀和思想的轻量版本。

三、带数字推演

[1,7,3,6,5,6] 为例,total = 28

i=0: left=0, right=27,不相等
i=1: left=1, right=20,不相等
i=2: left=8, right=17,不相等
i=3: left=11, right=11,命中

所以下标 3 是中心下标。注意判断 i=3 时,6 这个当前值不属于左侧,也不属于右侧。

四、代码模板

实现如下:

function pivotIndex(nums) {
  const total = nums.reduce((sum, x) => sum + x, 0)
  let leftSum = 0
  for (let i = 0; i < nums.length; i++) {
    const rightSum = total - leftSum - nums[i]
    if (leftSum === rightSum) return i
    leftSum += nums[i]
  }
  return -1
}

这个模板的关键是先判断,再更新 leftSum。如果顺序反了,当前元素就会被错误地算进左侧。

五、边界情况怎么理解

中心下标可以是 0。例如 [2,1,-1],下标 0 左侧为空,和为 0;右侧 1 + (-1) = 0,所以答案是 0。中心下标也可以是最后一个位置,只要左侧和等于 0

空区间和 = 0
当前元素不属于任何一侧
返回最左侧满足条件的下标

这些边界都能由同一个公式覆盖。

六、常见误区与追问

  • 误区:把当前元素加入左侧后再判断。 当前元素不属于左区间或右区间,加入会导致偏差。
  • 误区:认为中心下标必须在数组中间。 它可以在开头、末尾或任意位置。
  • 误区:忽略负数。 有负数时左右和仍然可以平衡,不能用单调或双指针替代。
  • 追问:为什么不用完整 prefix 数组? 只查询一次,维护滚动左和即可,空间更省。
  • 追问:如果有多个中心下标怎么办? 通常返回最左侧,遍历从左到右第一次命中即可。

这些点都围绕“当前位置不属于两边”这个细节。

七、加强记忆

中心下标记成“总和减左减当前,就是右边”。先算 total,遍历时 leftSum 只代表当前下标左侧,右侧由公式得到;判断平衡后再把当前值加入左侧。空区间和按 0 处理,所以开头和末尾都不需要特判。