给你一个整数数组 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
读一遍应该就懂了,不懂留言或者私信,看到第一时间解答
class Solution {
/**这个题目竟然有负数,所以不符合滑动窗口的条件
这个题我们需要用哈希表的解法,基本思路就是如果从0~i的累加值是x
前面某个位置0~j的累加和中有多少个x-k,那以i结尾的子数组就有多少个*/
public int subarraySum(int[] nums, int k) {
/**边界判断,也可以没有 */
if(nums.length == 1 && nums[0] != k) {
return 0;
}
/**定义一个hashmap,用来保存0~j位置的某个累加和出现了多少次 */
Map<Integer,Integer> countMap = new HashMap<>();
/**这里一定要放个0的值,因为很可能0位置的值就是k */
countMap.put(0,1);
int preSum = 0;
/**count用来统计结果数 */
int count = 0;
for(int i = 0; i < nums.length; i++) {
/**把当前值加到preSum里 */
preSum += nums[i];
/**当前的累加和是preSum,如果前面出现了preSum-k多少次,就有多少个以i位置结尾的子数组的和为k
如果没有preSum-k,则没有以i位置结尾的子数组满足这个条件
这里我们举个例子,比如当前的累加和是100,然后我们的k是20,那我们只需要看一下前面有多少个80就行了
这个80是啥呢,就是preSum - k */
if(countMap.containsKey(preSum - k)) {
count += countMap.get(preSum - k);
}
/**不管包含不包含,当前的值都要放进去,记住用原来的数量(或者0)+ 1*/
countMap.put(preSum, countMap.getOrDefault(preSum, 0) + 1);
}
return count;
}
}