给你一个整数数组 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
思路一 :双层for循环,枚举区间的开始和结束为止,求区间和。区间求和考虑用前缀和预处理一下。
思路二:考虑优化,使用单层for循环,对当前下标之前的值求和pre,放入map中进行计数,统计求和pre的个数。当pre-k存在map中时,结果加上pre-k的个数。
思路一:
c
class Solution {
public int subarraySum(int[] nums, int k) {
int[] sum = new int[nums.length+1];
for(int i = 1;i<=nums.length;i++){
sum[i] = sum[i-1]+nums[i-1];
}
int cnt = 0;
for(int r = 0;r<nums.length;r++){
for(int l = 0;l<=r;l++){
if(sum[r+1]-sum[l]==k)cnt++;
}
}
return cnt;
}
}
思路二:
c
class Solution {
public int subarraySum(int[] nums, int k) {
int res = 0;
int pre = 0;
Map<Integer, Integer> mp = new HashMap<>();
mp.put(0,1);
for(int i = 0; i<nums.length; i++){
pre += nums[i];
if(mp.containsKey(pre-k)){
res+=mp.get(pre-k);
}
Integer t = mp.getOrDefault(pre,0);
mp.put(pre,t+1);
}
return res;
}
}