560. 和为K的子数组
给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。
示例 1 :
输入:nums = [1,1,1], k = 2
输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。
说明 :
数组的长度为 [1, 20,000]。
数组中元素的范围是 [-1000, 1000] ,且整数 k 的范围是 [-1e7, 1e7]。
解题:
# 一开始采用暴力解法,超出了时间限制
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
result=0
for i in range(len(nums)):
s=nums[i]
if s==k:
result+=1
for j in range(i+1,len(nums)):
s+=nums[j]
if s==k:
result+=1
return result
# 改为如下代码
def subarraySum(nums, k):
dic = {}
# 注意此处如果没有dic[0]=1的话,后面必须要有对单个元素等于k的判断;如果有判断的话则不需要dic[0]=1
# dic[0]=1
acc, res = 0, 0
for num in nums:
acc += num
if acc == k:
res += 1
if acc - k in dic:
res += dic[acc - k]
dic[acc] = dic.get(acc, 0) + 1
return res
总结:
- 注意数组元素并不都大于0。
- 注意只有一个元素就满足k的情况。
- dict.get(key, default=None),参数:key – 字典中要查找的键。default – 如果指定键的值不存在时,返回该默认值。
- 字典:dic={}。
- 前缀和:该元素位置之前所有元素的总和。
- i到j之间子数组总和为k,则nums[j]-nums[i-1]=k,则有nums[i-1]=nums[j]-k,所以判断当前元素与k之间的差值是否是前若干元素总和即可,注意计数时并不都是+1,如果前若干元素总和=nums[j]-k的子数组个数大于1,则要全部加上,因为是不同的子数组。