LeetCode 724简单前缀和
寻找数组的中心下标 图解题解
这道题到底在问什么
给你一个整数数组 nums,请计算数组的中心下标。中心下标是数组中的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。如果中心下标位于数组最左端,则左侧数之和视为 0;位于最右端,则右侧数之和视为 0。返回最靠左的中心下标;如果不存在,返回 -1。
- 输入
- nums = [1,7,3,6,5,6]
- 输出
- 3
- 解释
- 下标 3 左侧和 1+7+3=11,右侧和 5+6=11。
- 输入
- nums = [1,2,3]
- 输出
- -1
最优解:一步一步想明白
- 3如果每个位置都重新求和,复杂度会到 O(n^2)。这题可以用一次总和和一个滚动 left 解决。
- 4循环不变量是:检查下标 i 之前,left 永远只包含 i 左侧的元素,不包含 nums[i] 本身。
- 5total = sum(nums); left = 0left 从 0 开始,因为还没站到任何下标,左侧没有元素。
- 6right = total - left - x站在下标 0,左侧和是 0,右侧和是 7+3+6+5+6=27,不相等。
- 7left += x离开下标 0 后,nums[0] 就会成为下一个位置的左侧元素。
- 8right = total - left - x下标 1 左侧只有 [1],left=1;右侧是 [3,6,5,6],right=20,不相等。
- 9left += x现在 left=1+7=8,代表下标 2 左侧的元素和。
- 10right = total - left - x下标 2 左侧和是 8,右侧和是 17,仍然不是中心下标。
- 11left += x更新后 left=11,也就是 [1,7,3] 的和。
- 12if left == right: return i下标 3 左侧和 11,右侧和 11,第一次相等,所以直接返回 3。
- 13return i因为从左到右扫描,第一次命中的下标天然就是最靠左的中心下标。
- 16顺序不能反:如果先 left += nums[i],left 就把当前元素也算进去了。
⚠️ 容易写错的地方
✗ 错:先 left += nums[i] 再判断
✓ 对:先判断 left == right,再更新 left
中心下标左右两侧都不包含 nums[i]。
✗ 错:忘记返回最靠左
✓ 对:从左到右第一次命中就返回
题目要求最靠左的中心下标。
✗ 错:left=0 时以为不合法
✓ 对:最左端左侧和视为 0
题目明确允许边界位置成为中心下标。
✗ 错:遇到负数就放弃前缀思路
✓ 对:负数不影响总和相减
这题只做加减,不依赖单调性。
完整代码(Python)
Python
class Solution:
def pivotIndex(self, nums):
total = sum(nums)
left = 0
for i, x in enumerate(nums):
right = total - left - x
if left == right:
return i
left += x
return -1复杂度
时间复杂度
O(n)
sum(nums) 扫一次,for 循环再扫一次。
空间复杂度
O(1)
只维护 total、left、right 等常数变量。
看不够?换成动画再走一遍
上面的推演每一步都对应一帧动画。点开交互动画版,能一步步看着 寻找数组的中心下标 的数据怎么变、指针怎么走,还能切 Python / Java / C++ 跟着练。
面试官可能追问
这道题为什么用「前缀和」,换最直接的暴力解会差在哪?+
前缀和抓住了本题的结构特征,把暴力解里重复的工作省掉;暴力解通常要多嵌套一层枚举,数据一大就超时。具体对比见上文「暴力解及其卡点」与「最优解逐步推演」两节。
时间复杂度为什么是 undefined?怎么推出来的?+
按上文复杂度小节的推导,时间复杂度为 undefined。
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。