题目 :
方法:前缀和+哈希表
- 判断数组大小,数组大小小于2则直接返回。
- 创建哈希表,将key==0置为-1。
- 初始化前缀和变量sum=0。
- 循环相加数组元素,每次循环相加后取模k。
- 判断取模后的值是否已存入哈希表。
- case1:如果取模后的值为0,则表示sum前缀和的值刚好为k的倍数。
- case2:如果取模后的值在哈希表中不存在,则存入值为数组下标的键sum。<前缀和,数组下标>
- case3-1:如果取模后的值在哈希表中存在,前i个元素和等于前j个元素和,相减后为0,则说明nums[i]~nums[j]的元素和为k的倍数。
- case3-2:判断当前下标和哈希表中已存入的下标是否相隔大于等于2。
代码实现:
C++:
class Solution {
public:
bool checkSubarraySum(vector<int>& nums, int k) {
int size=nums.size();
if(size<2)//数组元素少于2,则直接返回false
return false;
unordered_map<int,int> hash;
hash[0]=-1;//前0个元素和的数组下标为-1
int sum=0;
for(int i=0;i<size;++i){
sum=(sum+nums[i])%k;//前i个元素的前缀和 取模k
if(hash.count(sum)){
if(i-hash[sum]>=2)//判断子数组是否大于等于2
return true;
}
else{
hash[sum]=i;//存入hash<sum,i>
}
}
return false;
}
};
C:
//开源库“uthash.h”
struct HashTable{
int key;
int val;
UT_hash_handle hh;
};
bool checkSubarraySum(int* nums, int numsSize, int k){
if(numsSize<2)
return false;
struct HashTable *hashtable=NULL;
struct HashTable *tmp=(struct HashTable*)malloc(sizeof(struct HashTable));
tmp->key=0;
tmp->val=-1;
HASH_ADD_INT(hashtable,key,tmp);
int sum=0;
for(int i=0;i<numsSize;++i){
struct HashTable *tmp;
sum=(sum+nums[i])%k;
HASH_FIND_INT(hashtable,&sum,tmp);
if(tmp!=NULL){
if(i-tmp->val>=2)
return true;
}
else{
tmp=(struct HashTable *)malloc(sizeof(struct HashTable));
tmp->key=sum;
tmp->val=i;
HASH_ADD_INT(hashtable,key,tmp);
}
}
return false;
}