问题:
给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。
子数组是数组中元素的连续非空序列。
示例 1:
输入:nums = [1,1,1], k = 2
输出:2
分析:
子数组是连续的,那很容易想到就是要找到所有(i,j)对,符合下标i到j且包括i,j对应的元素之和为k,那就想到双重循环遍历i,j嘛,假设i=0,一边遍历j(0<=j<len(nums)),一边将j对应的元素加到变量num求和,并判断num等不等于k,但是这个时间复杂度O(n2)。
我们遍历i的时候,也要遍历每个j,那是否可以找到i,j之间很直接的一个关系,使得我们只遍历i/j,就可以对应找到满足关系的j/i,要为每个i一边遍历j,一边求和太麻烦了,我们直接首先计算出前缀和,然后根据prefix_num[j]-prefix_num[i-1]=k (i-1<j),只遍历j,找到前缀和为prefix_num[j]-k的下标数量,使用python的字典来实现哈希表,存取key-value。我们遍历j的同时,计算前缀和,把前缀和存入哈希表之前,判断哈希表里是否有key=prefix_num[j]-k,然后取出value(前缀和为prefix_num[j]-k的下标数量)(这样保证了i-1<j)。
特殊情况:j=0时,存在满足条件的i-1=-1,所以首先在哈希表里面加入(0,1),前缀和为0的一个下标有-1,数量为1。
代码实现:
class Solution(object):
def subarraySum(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
n=len(nums)
count=0
d=dict()
d[0]=1
prefix_num=0
for i in range(n):
prefix_num+=nums[i]
tmp=prefix_num-k
if tmp in d:
count=count+d[tmp]
if prefix_num not in d:
d[prefix_num]=0
d[prefix_num]=d[prefix_num]+1
return count