此题可用前缀和的思想来集体,所谓的前缀和就是用一个变量或者数组来储存数组sum的前x项和,而sum[i]-sum[j]即为第j+1项到第i项的和。
另一个点就是( sum[i]-sum[j] )%k=0可以转化为(sum[i])%k=(sum[j])%k
那么这个题的思路就是:可以将前缀和逐个对k取余,那么余数相等的两个子数组相减即可得一个对k取余为0的子数组。但是需要注意一点的是那些前缀和对k取余即为0的,则需要特殊处理。
可以创建一个对象来存储前缀和对k取余的信息。代码如下:
let subarraysDivByK = function(nums, k) {
let res=0
let m={0:1} //储存余数的 此处直接设置{0:1}是因为余数为0的子数组本身就是k的倍数,
// 所以没一个都要多加1
let sum=0 //数组的前缀和
for (let i = 0; i < nums.length; i++) {
let item=nums[i]
sum+=item
tem=(sum%k+k)%k //取前缀和的余数,之所以+k再取余是为了去除负数的影响
if (m[tem]) {
res+=m[tem]
m[tem]++
}else{
m[tem]=1
}
}
return res
};
参考资料: