题目
思路
- 这个仔细看一下题目,应该用双指针解会好一点,呃,但是不排序的话,用双指针好像不好做…润去题解
- 假设此时有个pre[i]为[0,i]的前缀和,那么,如果需要知道{[j…i]的子数组和为k}可以这样求 k=pre[i]-pre[j-1]。
- 那么可知pre[j-1]=pre[i]-k
- 如果每次都存下pre的值和出现的次数,遇到一个新的i的时候,就可以获得题意成立的j的个数,加上即可。
代码
public int subarraySum(int[] nums, int k) {
//返回的总数
int ans=0;
//pre走到哪里 因为只用关心前面的前缀和 所以直接用一个int接收即可
int pre=0;
//map存前缀和 值为该前缀和的出现次数
HashMap<Integer, Integer> map = new HashMap<>();
//有可能出现pre-k=0的情况,即所有数字相加等于最后的k,此时看做1个
map.put(0,1);
for(int i=0;i<nums.length;i++){
//首先求出[0,i]的前缀和
pre+=nums[i];
//根据pre[j-1]=pre[i]-k这个算式
if(map.containsKey(pre-k)){
//获得前缀和为 preSum - k 的个数,加到计数变量里
ans+=map.get(pre-k);
}
map.put(pre, map.getOrDefault(pre, 0) + 1);
}
return ans;
}