1、题目
给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目。
示例:
输入:A = [4,5,0,-2,-3,1], K = 5
输出:7
解释:
有 7 个子数组满足其元素之和可被 K = 5 整除:
[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]
提示:
1 <= A.length <= 30000
-10000 <= A[i] <= 10000
2 <= K <= 10000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/subarray-sums-divisible-by-k
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2、解法
int getcomb(int n)//求组合数
{
return n*(n-1)/2;
}
int subarraysDivByK(int* A, int ASize, int K){
int i,j;
int count=0;//子数组数量
int sum=0,temp=0;//sum:前缀和 temp:用于暂存前缀和余数
int mod[K];//利用数组下标来标记前缀和的余数,例:mod[1]=2即余数为1的有两个
memset(mod,0,sizeof(int)*K);
for(i=0;i<ASize;i++)//求出所有前缀和余数并放入mod数组分类
{
sum+=A[i];//求前缀和
temp=sum%K;
if(temp<0)//余数若为负数转换为整数
{
temp+=K;
}
mod[temp]++;
}
for(i=0;i<K;i++)//同余定理,余数相同的前缀和组合是k的倍数->a*k - b*k = c*k
{
if(mod[i]>0)//相同余数的两个数组合都是k的倍数
{
count+=getcomb(mod[i]);
}
}
if(mod[0]>0)//余数为0说明本身也可以被k整数
{
count+=mod[0];
}
return count;
}