什么是前缀和?
前缀和是一种预处理数组的技巧,能够让我们在 常数时间 O(1)
内快速计算任意区间 [i, j]
的和。它通过构建一个新的数组 prefix
,记录从起点到当前位置的累加和。
前缀和也有以下几种常见使用方式:
1. 一维前缀和(1D Prefix Sum)
特点:
构建一个 prefixSum 数组,prefixSum[i] = nums[0] + ... + nums[i - 1]
区间 [i, j] 的和为:prefixSum[j+1] - prefixSum[i]
适用场景:
多次查询数组某段区间和
判断某段是否满足某种和的条件(如等于 k)
举例:查账系统——快速查询某天到某天的总支出
你开发了一个查账小程序,用户经常问:
「我从第 3 天到第 7 天花了多少钱?」
为了不每次都去把这段加一遍,你提前计算好“截至每一天为止的总消费”,
比如第 8 天总共花了 500,第 3 天前花了 100
那第 3~7 天就是 500 - 100 = 400 元
对应题目:
2. 二维前缀和(2D Prefix Sum)
特点:
构建一个二维数组 prefix[i][j],表示从 (0,0) 到 (i-1,j-1) 矩阵区域的和
任意子矩阵 (x1, y1) 到 (x2, y2) 的和可以用 4 次前缀值相加减得出
适用场景:
图像分析、子矩阵求和
地图覆盖、区域得分等
举例:地图评分——快速查看一个区域总得分
你开发了一个游戏地图编辑器,用户画了一个 10x10 的热力图,想知道第 25 行,第 37 列这块区域总得分是多少。
你不能每次都挨个加,于是用前缀和矩阵,点击一下就能秒出结果。
对应题目:
3. 哈希前缀和(Prefix Sum + Hash Map)
特点:
利用哈希表记录某个前缀和出现的次数
用于快速判断是否存在某段子数组,和为目标值 k
适用场景:
子数组和为固定值的计数问题
子串、子数组计数问题(有负数时特别有用)
举例:风控报警系统——监测是否有某段消费正好为 k 元
你做的是反洗钱系统,要判断是否有某一段连续消费行为,恰好加起来为 1000 元。
你不能暴力查每一段,太慢。于是你记录:
“到当前这天为止,一共消费了多少”
然后看之前有没有哪天的累计消费是:当前总消费 - 1000
只要有,就说明中间这段正好是 1000 元。
对应题目: