题目描述
思路解析动画文字版
记住一条公式:区间 [i,j] 的和 = pre[j+1] − pre[i]。pre[k] 是「前 k 个数的和」,预处理一次,查询全靠它。
先给前缀和表放一条 pre[0]=0:还没取任何数时,和是 0。这条是后面减法能对齐的关键。
指针走到下标 0,这一格是 2。把它加到上一个前缀和上,得到新的前缀和。
pre[1] = 前一个前缀和 0 加上 2,等于 2(高亮那行就是刚算出的)。
指针走到下标 1,这一格是 4。把它加到上一个前缀和上,得到新的前缀和。
pre[2] = 前一个前缀和 2 加上 4,等于 6(高亮那行就是刚算出的)。
指针走到下标 2,这一格是 1。把它加到上一个前缀和上,得到新的前缀和。
pre[3] = 前一个前缀和 6 加上 1,等于 7(高亮那行就是刚算出的)。
指针走到下标 3,这一格是 3。把它加到上一个前缀和上,得到新的前缀和。
pre[4] = 前一个前缀和 7 加上 3,等于 10(高亮那行就是刚算出的)。
指针走到下标 4,这一格是 5。把它加到上一个前缀和上,得到新的前缀和。
pre[5] = 前一个前缀和 10 加上 5,等于 15(高亮那行就是刚算出的)。
扫一遍就把前缀和全建好了:pre=[0,2,6,7,10,15]。从现在起,任何区间查询都靠它做一次减法。
来了一个查询 sumRange(1, 3):求绿色高亮这一段(下标 1 到 3)的和。
套公式:这段的和 = 前 4 个之和 减 前 1 个之和 = pre[4] − pre[1] = 10 − 2。
10 减 2 等于 8。整段不用逐个相加,一次减法就得到答案 8。
来了一个查询 sumRange(0, 4):求绿色高亮这一段(下标 0 到 4)的和。
套公式:这段的和 = 前 5 个之和 减 前 0 个之和 = pre[5] − pre[0] = 15 − 0。
15 减 0 等于 15。整段不用逐个相加,一次减法就得到答案 15。
来了一个查询 sumRange(2, 4):求绿色高亮这一段(下标 2 到 4)的和。
套公式:这段的和 = 前 5 个之和 减 前 2 个之和 = pre[5] − pre[2] = 15 − 6。
15 减 6 等于 9。整段不用逐个相加,一次减法就得到答案 9。
三个边界:整段、单元素、含负数——前缀和公式都不用改。
三个高频追问:为何是 O(1)、带修改怎么办、二维如何推广。
参考代码
class NumArray: def __init__(self, nums): self.pre = [0] # pre[0] = 0 for x in nums: # 预处理前缀和 self.pre.append(self.pre[-1] + x) def sumRange(self, i, j): return self.pre[j+1] - self.pre[i] # 一次减法复杂度
- 预处理:O(n),建前缀和数组,把数组扫一遍
- 单次查询:O(1),只做一次减法 pre[j+1] − pre[i]
- 空间:O(n),多存一个长度 n+1 的前缀和数组
易错点
面试追问把动画讲成自己的话
追问前缀和为什么能把查询从 O(n) 降到 O(1)?
追问如果数组会被修改(某个元素变了)还能用前缀和吗?
追问二维版本怎么做?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
寻找数组的中心下标
LeetCode 724 · 简单 · 沿着 前缀和套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题