[优选算法专题四.前缀和——NO.29 和为 K 的子数组]
题目链接:
和为 K 的子数组
题目描述:
题目解析:
核心思路
利用前缀和与哈希表的结合,将时间复杂度从暴力解法的 O (n²) 优化至 O (n)。
1️⃣前缀和定义:设 sum[i]
表示数组前 i
个元素的和(即 nums[0] + nums[1] + ... + nums[i-1]
),则子数组 nums[j..i-1]
的和可表示为 sum[i] - sum[j]
。
2️⃣问题转化:若子数组 nums[j..i-1]
的和为 k
,则 sum[i] - sum[j] = k
,即 sum[j] = sum[i] - k
。因此,对于当前前缀和 sum[i]
,只需统计此前出现过的 sum[j] = sum[i] - k
的次数,即可得到以 i-1
为结尾的、和为 k
的子数组个数。
3️⃣哈希表作用:用哈希表 hash
存储前缀和的值与该值出现的次数,实时记录遍历过程中前缀和的出现频率,避免重复计算。
关键细节
-
初始化
hash[0] = 1
:当sum = k
时(即子数组从索引 0 开始到当前位置),sum - k = 0
,此时需用hash[0] = 1
来统计这种情况,否则会遗漏。 -
遍历顺序:先检查
hash
中是否存在sum - k
,再将当前sum
存入hash
,避免将当前sum
误算入统计(因为子数组必须是之前的前缀和与当前前缀和的差)。
复杂度分析
- 时间复杂度:O (n),其中
n
是数组长度。遍历数组一次,哈希表的插入和查询操作均为 O (1)(平均情况)。 - 空间复杂度:O (n),哈希表最多存储
n+1
个不同的前缀和(极端情况下所有前缀和均不重复)。