先明确
前缀和数组的定义
对一个数组a,我们的前缀和定义为
pre[i] = sum(a[0],…,a[i])
我们要求和为k的子数组,假设这个数组是从j开始 到i结束的
那么这个问题就等价于求
满足pre[i] - pre[j-1] == k 的[j,i]的个数
怎么求呢
我们可以先遍历数组a
当遍历到第i个时,我们可以求此位置的前缀和(从第0个位置开始,设置一个变量有,一直累加即可)
所以pre[i] = pre[i-1] + a[i]
到这里都很简单
接着,我们要找 对于这个pre[i],存在不存在、存在多少个j,构成满足pre[i] - pre[j-1] == k的区间[j,i]
怎么办呢?
我们现在有pre[i] 则 我们要找满足条件的pre[j]
则 我们就找有多少个pre[j-1] == pre[i] - k
因此 很容易想到,当我们计算出一个位置的前缀和时,我们用一个dict记录 前缀和为这个结果的位置 到目前为止 一共有多少个
因此 在 遍历开始之前 初始化一个控dict
在计算前缀(上面说“到这里都很简单”)结束后,立刻将这个结果更新到一个dict中
这样 我们在i位置,计算完pre[i]后
即可查找到符合条件的j-1的个数,即为当前情况下dict中键为pre[i]-k的值
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
if len(nums) == 1:# and nums[0] != k:
return 0 if nums[0] != k else 1
suma = 0
pre_dict = {0:1}
presum_list = []
last_sum = 0
for val in nums:
last_sum += val
presum_list.append(last_sum)
if last_sum - k in pre_dict:
suma += pre_dict[last_sum - k]
if last_sum in pre_dict:
pre_dict[last_sum] += 1
else:
pre_dict[last_sum] = 1
return suma