560
因为以i结尾的连续子数组,只需要找到是否存在i结尾的前缀的presum-K的hash值存在即可,即可找到将和为presum-k的前缀去掉即可。
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int,int>map;
map[0]=1;
int pre = 0;
int count = 0;
for(auto n:nums){
pre += n;
if(map.find(pre-k)!=map.end()){
count+=map[pre-k];
}
map[pre]++;
}
return count;
}
};
523
每个hash存放的是以i结束的节点之和的余数,和为rem
若i到j之间有和能被k整除的数,则
此时i到j节点之间的节点和为 rem+nk,j节点至为(rem+nk)%k,计算得到为rem%k,正好为i出的hash值,能证明有i和j处有相同的余数值,则i和j处有解。
class Solution {
public:
bool checkSubarraySum(vector<int>& nums, int k) {
unordered_map<int,int>mp;
int pre = 0;
mp[0]=-1;
for(int i = 0;i<nums.size();i++){
pre += nums[i];
if(k!=0){
pre = pre%k;
}
if(mp.find(pre)!=mp.end()){
if(i-mp[pre]>1){
return true;
}
}
else //没找到这个数,则入map,防止中间的数把坐标的数挤掉,不满足长度大于2的条件
mp[pre] = i;
}
return false;
}
};
974
保证取模后的结果为正数:
((x % MOD) + MOD) % MOD
class Solution {
public:
int subarraysDivByK(vector<int>& A, int K) {
int n = A.size();
unordered_map<int,int>mp;
mp[0]=1;
int pre = 0;
int res = 0;
for(int i = 0;i<n;i++){
pre += A[i];
int a = (pre%K + K) % K;
if(mp.find(a)!=mp.end()){
res+=mp[a];
}
mp[a]++;
}
return res;
}
};