力扣刷题Day 53:和为 K 的子数组(560)
1.题目描述
2.思路
方法1:灵茶山艾府佬的两次遍历法,先计算前缀和,然后遍历前缀和。
方法2:灵茶山艾府佬的一次遍历法,一边计算前缀和,一边遍历前缀和。
P.S. 至于为什么要用前缀和,是因为,nums[i]到nums[j - 1]的元素和为k可用前缀和表示为s[j] - s[i] = k,所以当s[i] == s[j] - k的时候nums[i]到nums[j - 1]的元素和为k,这样这道题就非常了然了。
3.代码(Python3)
方法1:
class Solution:def subarraySum(self, nums: List[int], k: int) -> int:# 计算前缀和presums = [0] * (len(nums) + 1)for i, num in enumerate(nums):presums[i + 1] = presums[i] + num# 遍历前缀和res = 0count = defaultdict(int)for presum in presums:res += count[presum - k]count[presum] += 1return res
方法2:
class Solution:def subarraySum(self, nums: List[int], k: int) -> int:res = presum = 0count = defaultdict(int)count[0] = 1for num in nums:presum += numres += count[presum - k]count[presum] += 1return res
4.执行情况
方法1:
方法2:
5.感想
最开始想尝试用滑动窗口做的,但是本题nums包含负数,而滑动窗口需要满足单调性。