给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。
子数组是数组中元素的连续非空序列。
示例 1:
输入:nums = [1,1,1], k = 2 输出:2 示例 2:
输入:nums = [1,2,3], k = 3 输出:2
提示:
1 <= nums.length <= 2 * 104 -1000 <= nums[i] <= 1000 -107 <= k <= 107
前缀和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution : def subarraySum (self, nums: list [int ], k: int ) -> int : prefix = [0 ] * (len (nums) + 1 ) result = 0 for i in range (len (nums)): prefix[i + 1 ] = prefix[i] + nums[i] for i in range (len (nums)): for j in range (i + 1 , len (nums) + 1 ): if prefix[j] - prefix[i] == k: result += 1 return result
前缀和+hash
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def subarraySum (self, nums: list [int ], k: int ) -> int : prefix = 0 result = 0 count = {0 : 1 } for num in nums: prefix += num if prefix - k in count: result += count[prefix - k] if prefix in count: count[prefix] += 1 else : count[prefix] = 1 return result
prefix[i] = nums[0] + nums[1] + … + nums[i-1] sum(i, j) = prefix[j] - prefix[i]
利用前缀和,避免重复计算子数组和,复杂度:O(n²) 但还有优化空间
核心优化 → 前缀和 + 哈希表 当遍历到 prefix[j] 时,只需要知道之前有没有出现过 prefix[j] - k 用哈希表 count_map 记录每个前缀和出现次数 遍历一次即可统计所有子数组数量
1 2 3 4 5 prefix = 0 count_map = {0 :1 } result = 0
1 2 3 4 5 6 7 8 9 for num in nums: prefix += num if prefix - k in count_map: result += count_map[prefix - k] count_map[prefix] = count_map.get(prefix, 0 ) + 1