1、题目来源
2、题目描述
给你一个整数数组 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
3、题解分享
// 方法一:
class Solution {
public int subarraySum(int[] nums, int k) {
//枚举,确定左右区间进行累加
int ans = 0;
int n = nums.length;
for(int i = 0;i<n;++i){
int sum = 0;
for(int j = i;j<n;++j){
sum += nums[j];
if(sum == k){
++ans;
}
}
}
return ans;
}
}
// 方法二:
class Solution {
public int subarraySum(int[] nums, int k) {
// 思路:前缀和 + Hash,使用Hash表来存储每个前缀和(指从下标0开始的)出现的次数,
//然后遍历nums数组时,使用hash找出需要减去的前缀和所出现的次数
int ans = 0;
int n = nums.length;
Map<Integer, Integer> tab = new HashMap<>();
int preSum = 0;
// 为了应对 nums[0] +nums[1] + ... + nums[i] == k 的情况的, 也就是从下标 0 累加到下标 i
tab.put(0,1);
for(int i = 0;i<n;++i){
preSum += nums[i];
if(tab.containsKey(preSum - k)){
ans += tab.get(preSum - k);
}
tab.put(preSum,tab.getOrDefault(preSum,0)+1);
}
return ans;
}
}