Given an integer array, find the maximum number of sums of adjacent elements that are divisible by n.
Example 1:
input: long[] array = [1, 2, 3], n = 7
output: 0
Example 2:
input: long[] array = [1, 2, 4], n = 7
output: 1
Example 3:
input: long[] array = [2, 1, 2, 1, 1, 2, 1, 2], n = 4
output: 6
Constraints:
array.length = 50000
array[index] <= 2^31 - 1
n <= 2^31 - 1
Currently, this is my code:
public static int maxSums(long[] array, long n) {
int count = 0;
if (array.length == 1 && array[0] == n) {
return 1;
} else {
for (int i = 0; i < array.length; i++) {
long sum = 0;
for (int j = i; j < array.length; j++) {
sum += array[j];
if (sum % n == 0) {
count++;
}
}
}
}
return count;
}
which is essentially the window sliding technique. However, this code runs with time complexity O(n^2) which is pretty slow, and results in Apex CPU Time Limit Exceeded towards the higher end of the constraints. Is there a faster way to solve this?
An approach I just thought of is
O(n*m), wherenis the actualnparameter andmis the array length.The algorithm remembers for every subsequence up to the current index what reminder the sequence sum has. This information is stored inside the array called
currentMod.When iterating over the input array this
currentModis updated. We simply add to each possible modulo value of iterationi-1the value of the input array at indexi. The updated array includes the number of subsequence sums ending at indexifor each possible reminder:0,1,2up ton-1.The element first element of
tmpModat indexiincludes the number of subsequences that end at indexiand have a sum divisible byn. Therefore, we add them to our final result.Here is the algorithm:
P.S.: This algorithm is not strictly better/worse than yours. It depends on another input value. This means it depends on your inputs what is more efficient. My algorithm is only better for a case with large arrays and low
nvalues.EDIT: After a lot of thinking and testing I think I found a good solution. It is
O(n)in time complexity. It is alsoO(n)in space complexity as there can be at mostndifferent remainders withnvalues in the array.The algorithm keeps track of the current remainder, which is dividable by the input
nfrom the start. For each new subsequence, we add the1at the current remainder. In this way, we already define which total sum (mod n) we need that the subsequence is dividable byn.Also, some comparisons to show that it should work out:
len(array)=50000andn=1000:len(array)=50000andn=1000000: