题目:给定一个整数数组和一个整数 k ,请找到该数组中和为 k 的连续子数组的个数。
示例1:
输入:nums = [1,1,1], k = 2
输出: 2
分析:首先想到的滑动窗口算法来解决,但是这里存在负数,指针移动存在多种可能,所以滑动窗口算法不适合该题。可以使用前缀和算法解决。
前缀和
:顾名思义,就是一个数组的某项下标及某项下标之前的元素的和。
解题思路:
因为每次计算需要获取前几次的结果进行对比,所以可以使用哈希表的方式进行存储结果。
1、初始化一个哈希表、计算前缀和的变量sum、计算满足条件的子数组数量的变量count.
2、遍历数组,计算前缀和sum
3、在哈希表中搜索sum-k的key,若存在则说明存在满足条件的连续子数组,并获取其出现的次数。
4、将每次得到的前缀和sum出现的次数加1。
5、注意边界值问题:如果以nums[0]开头的子数组满足条件时,此时哈希表中为空,无法计算个数,所以需要默认插入一个{0:1}键值对。
class Solution {
public int subarraySum(int[] nums, int k) {
//前缀和
int sum = 0;
//统计个数
int count = 0;
//初始化哈希表
Map<Integer,Integer> map = new HashMap<>();
//如果数组nums[0]开头的数组就满足题意,此时map为空,需要先插入一个{0:1}
map.put(0,1);
//遍历数组
for(int num:nums) {
sum+=num;
//若在哈希表中查到sum-k的值key,说明有满足题意的连续子数组
count+=map.getOrDefault(sum-k, 0);
//在哈希表中插入前缀和以及出现该前缀和的次数
map.put(sum,map.getOrDefault(sum, 0)+1);
}
return count;
}
}