这里是题目描述:LeetCode-974.和可被 K 整除的子数组
首先解决子数组元素和问题,假设有数组sum
,sum[i]
记录从开头到第i
个元素的累加和,则sum[j]-sum[i-1]
表示从第i
个元素到第j
个元素(j>=i)
的子数组的元素和
接下来介绍同余定理:对于两个数a
、b
,如果有a%k==b%k
,则(a-b)%k==0
。因此如果有sum[i]%k==sum[j]%k
,则(sum[j]-sum[i])%k==0
。由此,我们可以 维护一个哈希表,哈希表的键是sum[i]
对k
的余数,对应的值是等于某一余数的sum[i]
的个数; 最后可被k
整除的子数组的计算方法是:假设哈希表的值是v
,最终结果是所有键值对对应的v(v-1)/2
的和。
我们还需要在建立哈希表后,为其加入(key=0,value=1)
,用来表示没有加任何数组中的元素时,累加和为0
,对k
取余为0
的情况;还有一点需要注意,当计算出来的余数是负数是,处理成对应的正数值
题解代码:
class Solution {
public int subarraysDivByK(int[] A, int K) {
HashMap<Integer,Integer> hashMap=new HashMap<>();
int sum=0;
hashMap.put(0,1);
for(int i=0;i<A.length;i++)
{
sum+=A[i];
int mod=sum%K;
if(mod<0) //注意处理余数是负数的情况
{
mod=mod+K;
}
if(!hashMap.containsKey(mod))
{
hashMap.put(mod,1);
}
else
{
hashMap.put(mod,hashMap.get(mod)+1);
}
}
int res=0;
for(int key:hashMap.keySet())
{
int value=hashMap.get(key);
res+=(value-1+1)*(value-1)/2;
}
return res;
}
}
时间复杂度:O(n)
空间复杂度:O(n)