示例:-
输入数组
int [] nums = {4,3,1,2,1,5,2};
K 是 3
连续求和
4,7,8,10,11,16,18
将上面的连续和数组除以3
1,1,2,1,2,1,0
所以我们有四个 1,两个 2,一个 0
所以总数将是 (4*3)/2 + (2*1)/2 + (2*1)/2 = 8
(4*3)/2 来自从四个中选择任意两个 1,即 nC2 = n(n-1)/2
这是程序
public static long countSubArrayDivByK(int k, int[] nums) {
Map<Integer, Integer> modulusCountMap = new HashMap<Integer, Integer>();
int [] consecSum = new int[nums.length];
consecSum[0]=nums[0];
for(int i=1;i<nums.length;i++){
consecSum[i]= consecSum[i-1] +nums[i];
}
for(int i=0;i<nums.length;i++){
consecSum[i]= consecSum[i]%k;
if(consecSum[i]==0 && modulusCountMap.get(consecSum[i])==null){
modulusCountMap.put(consecSum[i], 2);
}else{
modulusCountMap.put(consecSum[i], modulusCountMap.get(consecSum[i])==null ? 1 : modulusCountMap.get(consecSum[i])+1);
}
}
int count = 0;
for (Integer val : modulusCountMap.values()) {
count = count + (val*(val-1))/2;
}
return count;
}
上述优化版
static long customOptimizedCountSubArrayDivByK(int k, int[] nums) {
Map<Integer, Integer> modulusCountMap = new HashMap<Integer, Integer>();
int [] quotient = new int[nums.length];
quotient[0]=nums[0]%3;
if(quotient[0]==0){
modulusCountMap.put(quotient[0], 2);
}else{
modulusCountMap.put(quotient[0], 1);
}
for(int i=1;i<nums.length;i++){
quotient[i]= (quotient[i-1] + nums[i])%3;
if(quotient[i]==0 && modulusCountMap.get(quotient[i])==null){
modulusCountMap.put(quotient[i], 2);
}else{
modulusCountMap.put(quotient[i], modulusCountMap.get(quotient[i])==null ? 1 : modulusCountMap.get(quotient[i])+1);
}
}
int count = 0;
for (Integer val : modulusCountMap.values()) {
count = count + (val*(val-1))/2;
}
return count;
}