给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目java
输入 :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]
复制代码
利用双循环将全部可能的连续子数组枚举出来,求出子数组的和
sum
,如sum
能够整除K,则解法数+1。数组
定于一个默认为零的余数
mod
,遍历数组,余数mod
与数组的值求和除于K得出新的余数余数mod
,每出现一次余数mod
,则remainder[mod]
的值+1,由于余数每出现一次说明存在一个解。学习
/** * 暴力解法,枚举全部连续数组的结果 * @param A * @param K */
public static int forSolution(int[] A, int K) {
int res = 0;
for (int i = 0; i < A.length; i++) {
int sum = A[i];
if (sum % K == 0) ++res;
for (int j = i + 1; j < A.length; j++) {
sum += A[j];
// 被K整除
if (sum % K == 0) ++res;
}
}
return res;
}
复制代码
/** * 同余定理 * @param A * @param K * @return */
public static int remainder(int[] A, int K) {
// 新new 一个余数大小的数组
int[] remainder = new int[K];
// 默认有一个解
remainder[0] = 1;
// 余数
int mod = 0;
// 求解个数
int res = 0;
for (int n: A) {
mod = (mod + n) % K;
// 若是余数为负数 咱们将余数转为正余数
if (mod < 0) mod += K;
res += remainder[mod];
remainder[mod]++;
}
return res;
}
复制代码