题目
给你一个整数数组 nums
和一个整数 k
,请你统计并返回 该数组中和为 k
的子数组的个数 。
子数组是数组中元素的连续非空序列。
示例
示例 1:
输入:nums = [1,1,1], k = 2 输出:2示例 2:
输入:nums = [1,2,3], k = 3 输出:2
分析
前缀和+哈希表
前缀和是一种常见的算法技巧,主要用于解决区间求和的问题。其核心思想是将数组的前缀和(从数组开头到当前位置的所有元素的累加和)预先计算出来,这样可以在后续的查询中快速获取任意区间的和。
对于一个数组 nums
,前缀和数组 prefixSum
的定义如下:
prefixSum[i] = nums[0] + nums[1] + ... + nums[i-1]
即 prefixSum[i]
表示从数组 nums
的第一个元素到第 i-1
个元素的和。
有了前缀和数组后,可以快速计算任意区间 [i, j]
的和:
sum(i,j) = prefixSum[j+1] - prefixSum[i]
计算是常数时间复杂度 O(1)
,因为只需要访问前缀和数组的两个元素。
时间复杂度:O(),
为数组长度
空间复杂度:O(),
为数组长度
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int, int> prefixSumCount;
prefixSumCount[0] = 1; // 处理以第一个元素为结束的子数组情况
int count = 0;
int prefixSum = 0;
for (int num : nums) {
prefixSum += num;
if (prefixSumCount.find(prefixSum - k) != prefixSumCount.end()) {
count += prefixSumCount[prefixSum - k];
}
prefixSumCount[prefixSum]++;
}
return count;
}
};