📅  最后修改于: 2023-12-03 14:54:20.777000             🧑  作者: Mango
子数组是指一个数组中连续的一段元素构成的数组,比如:
[1, 2, 3, 4]
[1, 2]
[3, 4]
[2, 3, 4]
都是数组 [1, 2, 3, 4]
的子数组。
给定一个整数数组 nums
和一个整数 K
,你需要找到该数组中和至少为 K
的连续子数组的个数。
示例:
输入: nums = [1,2,3,4], k = 7
输出: 0
解释: 该数组中不存在和至少为 7 的连续子数组。
输入: nums = [3,2,3,1,2,4,5,5,6], k = 7
输出: 6
解释: [3,2,3], [2,3,1,2], [3,1,2,4], [1,2,4,5], [2,4,5], [5,5,6] 是和至少为 7 的连续子数组。
我们可以用前缀和来解决这个问题。对于一个区间 $[i,j]$ ,若前缀和 $sum_j \geqslant sum_i + K$ ,则说明从 $i$ 到 $j$ 存在一个子数组和至少为 $K$。
因此我们可以用一个变量 count
记录子数组的数量,每次遍历到下一个元素时,我们就遍历该元素前面的所有前缀和,看看有几个前缀和满足上面的条件。
具体实现见下方代码片段。
def subarray_sum(nums, k):
count = 0
pre_sum = 0
prefix_sum = {0: 1} # 存储前缀和及其出现次数
for i in range(len(nums)):
pre_sum += nums[i]
if pre_sum - k in prefix_sum:
count += prefix_sum[pre_sum - k]
prefix_sum[pre_sum] = prefix_sum.get(pre_sum, 0) + 1
return count
代码解释:
count
记录子数组的数量;pre_sum
记录当前的前缀和;prefix_sum
用字典存储前缀和及其出现次数;nums
,每次更新前缀和 pre_sum
;pre_sum - k
在字典中出现过,则说明从上一次出现的位置到当前位置的子数组和至少为 k
,更新 count
;prefix_sum
。