题目
给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k的子数组的个数。子数组是数组中元素的连续非空序列。

思路:暴力解,遍历每个子数组,固定起点i,j从 i 往后累加,每累加一次判断总和t是否等于 k,相等就计数 + 1。
class Solution(object):
def subarraySum(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
n = len(nums)
res = 0
if n == 0:
return 0
i = 0
j = 0
t = 0
while i < n :
j = i
t = 0
while j < n :
t += nums[j]
if t == k :
res += 1
j += 1
i += 1
return res
时间复杂度 O (n²),大数据会超时
改进:
前缀和 + 哈希表思路:
子数组 nums j ... i‑1 的总和 = pre_sumi − pre_sumj 也就是:从下标 j 到 i‑1 这一段连续区间的和 = 两个前缀和相减。
我们希望这段子数组的和等于 k:
(pre_sumi - pre_sumj = k) 变形:
{pre_sumj = pre_sumi - k})
当我们遍历到位置 i,当前前缀和是 pre_sumi。 我想找:之前有没有出现过前缀和等于 pre_sumi‑k。
每出现过 1 次,就代表找到 1 个子数组,和为 k。
如果这个前缀和历史上出现过 3 次,那就一下子新增 3 个答案。
class Solution(object):
def subarraySum(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
from collections import defaultdict
n = len(nums)
res = 0
if n == 0:
return 0
prefic_map = defaultdict(int)
prefic_sum = 0
prefic_map[0] = 1
for i in range(n) :
prefic_sum += nums[i]
if (prefic_sum - k) in prefic_map :
res += prefic_map[prefic_sum - k]
prefic_map[prefic_sum] += 1
return res