给定一个整数数组 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
因为是求子数组的和
可以用前缀和相减得到
设置数组s[], 就是前缀和
然后两个前缀的差能被k整除,那他们两mod K的余数也肯定相同
设置数组c[k]
就是c[i] 就是s中mod K 为i的个数
最后按照排列组合的原理
求所有Ci2的和
举例 对于A= [4,5,0,-2,-3,1] K = 5,
s = [0, 4, 9, 9, 7, 4, 5] ,
c = [2, 0, 1, 0, 4] 代表有s中有两个元素的余数都为0(即0和5),1个元素的余数为2(即7),四个元素的余数为4(即4994)
所以在保证余数相同的情况下,取出两个数都可以得到一组答案。对于这个例子答案就是 C22 + C12 + C42 = 1 + 0 + 6 = 7
#include <iostream>
#include <vector>
using namespace std;
int subarraysDivByK(vector<int>& A, int K) {
const int len = A.size();
const int k = K;
int i;
int s[30002] = {0};
int c[10001] = {0};
int sum = 0;
for(i = 0; i < len; i++){
s[i + 1] = s[i] + A[i];
}
for(i = 0; i <= len; i++){
c[s[i] % K]++;
}
for(i = 0; i < k; i++){
sum = sum + ((c[i] * (c[i] - 1)) / 2);
}
return sum;
}
int main(){
int a[] = { -2 };
vector<int> A(a, a + 1);
int re = subarraysDivByK(A, 6);
cout << re << endl;
}