
Problem Statement
The task is to count the number of contiguous subarrays within an integer array nums
, where the sum of the elements in the subarray is divisible by a given integer k
. The elements in the array, as well as the subarrays derived from it, can take on any integer value, positive or negative. Understanding that a "subarray" refers to a sequence of one or more elements that are contiguous segments of the main array, the solution should efficiently determine the count of such subarrays where the sum meets the divisibility criterion.
Examples
Example 1
Input:
nums = [4,5,0,-2,-3,1], k = 5
Output:
7
Explanation:
There are 7 subarrays with a sum divisible by k = 5: [4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]
Example 2
Input:
nums = [5], k = 9
Output:
0
Constraints
1 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
2 <= k <= 104
Approach and Intuition
The problem can be approached by focusing on the sum of subarrays and checking for divisibility by k
. Here's the step-by-step plan:
Utilize a Hash Map for Frequency Count of Remainders: As you iterate through the array, for each element, maintain a cumulative sum. For each new cumulative sum, compute the remainder of this sum when divided by
k
. Store and update the frequency of each unique remainder in a hash map.Understanding Remainder Behavior: The remainder, when divided by
k
, could potentially be negative (if the numbers innums
are negative andk
is positive, for example). Volatility in remainder signs can be normalized by adjusting remainders: if a remainder is negative, simply addk
to it to make it positive.Leverage the Pigeonhole and Prefix Sum Principle: The primary insight here leans on the idea of prefix sums. Specifically, if two prefix sums yield the same remainder upon division by
k
, then the elements lying between these two prefixes sum up to some multiple ofk
(hence, are divisible byk
).Count Potential Subarrays: Every time a remainder repeats, it means there are multiple subarrays (ending at different indices) which have sums divisible by
k
. Use the hash map to count these occurrences. For each remainder, if it has been seenn
times before, then there aren
subarrays ending at the current index that can be formed which have sums divisible byk
.
This approach capitalizes on both the properties of remainders and the utility of hash maps for efficient frequency counts, ensuring that each subarray is checked for divisibility without explicitly computing the sum for every possible subarray, thereby improving efficiency.
Solutions
- C++
- Java
class Solution {
public:
int subarraysWithSumDivisibleByK(vector<int>& array, int divisor) {
int length = array.size();
int currentMod = 0, totalCount = 0;
vector<int> remainderCount(divisor);
remainderCount[0] = 1;
for (int element : array) {
currentMod = (currentMod + element % divisor + divisor) % divisor;
totalCount += remainderCount[currentMod];
remainderCount[currentMod]++;
}
return totalCount;
}
};
The provided C++ code defines a solution for finding the count of subarrays within an integer array where the sum of the elements is divisible by a given divisor K
. The function subarraysWithSumDivisibleByK
accepts two parameters: a vector array
and an integer divisor
. It utilizes the properties of modulo operation to efficiently compute the number of such subarrays.
Here's how the function works:
Initialize
length
to hold the size of the input array.Initialize
currentMod
to store the current prefix sum modulus andtotalCount
to track the total number of valid subarrays.Create a vector
remainderCount
of sizedivisor
to store the frequency of each modulus value in prefix sums, with an initial count of one for the0
modulus to account for sums that are exactly divisible bydivisor
.Loop over each element of the array:
- Update
currentMod
by adding the current element's modulus value, adjusted for negative sums by addingdivisor
and taking the modulus again. - Increment
totalCount
by the count of previous prefix sums that share the same modulus ascurrentMod
, which means their difference is divisible bydivisor
. - Increment the count of the current modulus in
remainderCount
.
- Update
The function ultimately returns totalCount
, which represents the number of subarrays where the sum is divisible by divisor
. This approach ensures a comprehensive check through the use of modular arithmetic, optimizing the process to find qualifying subarrays efficiently using a time complexity dependent on the size of the array and the divisor.
class Solution {
public int countSubarraysDivisibleByK(int[] array, int divisor) {
int length = array.length;
int cumulativeModulo = 0, totalCount = 0;
int[] remainderGroups = new int[divisor];
remainderGroups[0] = 1;
for (int value : array) {
cumulativeModulo = (cumulativeModulo + value % divisor + divisor) % divisor;
totalCount += remainderGroups[cumulativeModulo];
remainderGroups[cumulativeModulo]++;
}
return totalCount;
}
}
This Java solution tackles the problem of counting the number of subarrays from a given array where the sum of elements is divisible by a specified value, K. The approach utilizes a cumulative sum and the modulo operation to efficiently compute the result.
Here's a step-by-step explanation of how the solution works:
Initialize
length
to the size of the input array for easy reference.Declare
cumulativeModulo
to store the ongoing sum of array values modulodivisor
. Start withtotalCount
to count the number of subarrays meeting the criteria.Create an array
remainderGroups
to track how many times each modulo value has occurred so far with a size equal todivisor
. Initialize the first element to 1 to account for the subarray consisting of the very first element if it is divisible bydivisor
.Iterate through each element in the input array:
- Update
cumulativeModulo
by adding the current value modulodivisor
and adjust for any negative values to ensure all remainders are positive. - Increase
totalCount
by the count of subarrays that have the samecumulativeModulo
value recorded inremainderGroups
. This is because if two subarrays have the same remainder when divided bydivisor
, the subarray between them has a sum that is divisible bydivisor
. - Increment the count for the current
cumulativeModulo
inremainderGroups
.
- Update
Return the total count of divisible subarrays.
The solution leverages the properties of the modulo operation and prefix sums to elegantly solve a potentially complex problem using a linear time algorithm that is both efficient and easy to understand.
No comments yet.