给你一个整数数组nums和一个整数k ,请你统计并返回该数组中和为k的子数组的个数 。
子数组是数组中元素的连续非空序列。
示例 1:
输入:nums = [1,1,1], k = 2
输出:2
示例 2:
输入:nums = [1,2,3], k = 3
输出:2
核心思路:
转化子数组的和问题:
- 假设我们有两个前缀和 prefix_sum[i] 和 prefix_sum[j](其中 i < j)。那么,nums[i+1] 到 nums[j] 这一段子数组的和就是 prefix_sum[j] - prefix_sum[i]。
- 如果要使得某一段子数组的和为 k,即 prefix_sum[j] - prefix_sum[i] = k,可以转化为:prefix_sum[j] = prefix_sum[i] + k。
cpp
#include <vector>
#include <unordered_map>
#include <iostream>
using namespace std;
class Solution
{
public:
int subarraySum(vector<int>& nums, int k)
{
int count = 0; // 记录和为 k 的子数组个数
int prefix_sum = 0; // 前缀和
unordered_map<int, int> prefix_sum_count; // 用于存储每个前缀和出现的次数
prefix_sum_count[0] = 1; // 初始时前缀和为0出现一次
for (int num : nums)
{
prefix_sum += num;
if (prefix_sum_count.find(prefix_sum - k) != prefix_sum_count.end())
{
count += prefix_sum_count[prefix_sum - k];
}
prefix_sum_count[prefix_sum]++;
}
return count;
}
};
int main()
{
Solution solution;
vector<int> nums1 = { 1, 1, 1 };
int k1 = 2;
int result1 = solution.subarraySum(nums1, k1);
vector<int> nums2 = { 1, 2, 3 };
int k2 = 3;
int result2 = solution.subarraySum(nums2, k2);
return 0;
}