原题链接:560. 和为 K 的子数组 – 力扣(LeetCode)
这题需要用到前缀和,用完前缀和之后不应该去枚举左右两个端点,太低效
可以使用一个hashmap来同步记录,当前遍历到的下标前,有多少个tp-k,也就是有多少个子区间,这里需要注意s[0]也需要加入,区间和是构建成两个前缀和的差,s[0]加入map就是为了可能有的区间就是以第一个为开头。同时也不能用滑动窗口,因为滑动窗口需要满足单调性。
class Solution {
public int subarraySum(int[] nums, int k) {
int n = nums.length;
int [] s = new int[n+1];
for(int i = 0;i<n;i++){
s[i+1] = s[i] + nums[i];
}
HashMap<Integer,Integer> map = new HashMap<>();
int count = 0;
//思路巧妙的一点是遍历过程中同步加
//可以直接得到左边有几个值等于tp-k,也就是多少个子区间
for(int tp : s){
count += map.getOrDefault(tp-k,0);
//merge函数,如果key = tp 不存在,就设置为1
//如果key = tp存在,就将tp对应value和1传入sum函数,返回值作为tp的value
map.merge(tp,1,Integer::sum);
}
return count;
}
}