📅  最后修改于: 2023-12-03 15:25:40.332000             🧑  作者: Mango
给定一个整数数组 nums
,请你计算并返回满足以下条件的非空连续子数组的数量:该子数组的长度、元素和均为 k
。
输入: nums = [1,1,1], k = 2
输出: 2
解释:
子数组 [1,1] 和 [1,1] 满足长度和元素和都为 2,因此满足条件的子数组总共有 2 个。
输入: nums = [1,2,3], k = 3
输出: 2
解释:
子数组 [2,1] 和 [3] 满足长度和元素和都为 3,因此满足条件的子数组总共有 2 个。
我们可以使用一个前缀和数组 preSum
,其中 sum[i]
表示从数组的第一个元素到第 $i$ 个元素的和。
对于 preSum
数组中的每个元素 preSum[i]
,我们需要找到满足以下条件的 preSum[j]
:
$$ preSum[j] - preSum[i-1] = k $$
上式表达的意思是:$i$ 和 $j$ 之间的连续子数组的和为 $k$。因此我们可以使用一个哈希表 countMap
,其中:
preSum[i] - k
,表示满足 $preSum[j] - preSum[i-1] = k$ 的 $preSum[i-1]$ 的数量。i
之前,有多少个前缀和等于 preSum[i] - k
。然后我们遍历数组,在遍历到位置 i
时,我们计算 preSum[i]
,并查找哈希表中是否有键为 preSum[i] - k
的项,如果有,则将对应项的值累加到结果中。
最后我们将 preSum[i]
添加到哈希表中,以便我们可以找到和它相等的前缀和。
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
countMap = {0: 1}
preSum = 0
count = 0
for num in nums:
preSum += num
if preSum - k in countMap:
count += countMap[preSum - k]
if preSum in countMap:
countMap[preSum] += 1
else:
countMap[preSum] = 1
return count
因此总时间复杂度为 $O(n)$。
哈希表最多需要存储 $n+1$ 个元素,因此空间复杂度为 $O(n)$。