1 预备知识
2 示例和解题思路
例一
解题思路
对于本题我们利用pre记录前缀和:pre[i]=pre[i-1]+nums[i],这个题目的目标就是求和为k的子数组,如果一个pre[k1]-pre[k2]==k就说明,在k1-k2区间内的子数组的和为k。
注:要首先在数组内加入map.put(0,1),以防止整个数组的和为k
代码
class Solution {//前缀和加hashmap
public int subarraySum(int[] nums, int k) {
Map<Integer,Integer> map=new HashMap<>();
int pre=0;//用于记录前缀和
int ans=0;//
map.put(0, 1);
for(int i=0;i<nums.length;i++){
pre+=nums[i];
if(map.containsKey(pre-k)){
ans+=map.get(pre-k);
}
map.put(pre,map.getOrDefault(pre,0)+1);
}
return ans;
}
}
例二
解题思路
利用pre记录前缀和(记录的是pre%k),如果pre[k1]-pre[k2]==0就说明,在k1-k2这段子数组可以被k整除。
注:提前put(0,1)和上题思路相同
代码
class Solution {
public int subarraysDivByK(int[] nums, int k) {
Map<Integer,Integer>map=new HashMap<>();
map.put(0,1);//对于sum(mod k)==0可以得到
int pre=0;
int ans=0;//记录前缀和模k相同的
for(int num:nums){
pre+=num;
pre=(pre%k+k)%k;//防止pre为负数的时候
//map.put(pre,0);
ans+=map.getOrDefault(pre,0);
map.put(pre,map.getOrDefault(pre,0)+1);
}
return ans;
}
}