Given an array A
of integers, return the number of (contiguous, non-empty) subarrays that have a sum divisible by K
.
Example 1:
Input: A = [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]
Note:
1 <= A.length <= 30000
-10000 <= A[i] <= 10000
2 <= K <= 10000
Approach 1: Prefix Sums and Counting
Intuition
As is typical with problems involving subarrays, we use prefix sums to add each subarray. Let P[i+1] = A[0] + A[1] + ... + A[i]
. Then, each subarray can be written as P[j] - P[i]
(for j > i
). Thus, we have P[j] - P[i]
equal to 0
modulo K
, or equivalently P[i]
and P[j]
are the same value modulo K
.
Algorithm
Count all the P[i]
's modulo K
. Let's say there are values . Then, there are possible subarrays.
For example, take A = [4,5,0,-2,-3,1]
and K = 5
. Then P = [0,4,9,9,7,4,5]
, and :
- With (at , ), it indicates subarray with sum divisible by , namely .
- With (at , , , ), it indicates subarrays with sum divisible by , namely , , , , , .
class Solution {
public int subarraysDivByK(int[] A, int K) {
int N = A.length;
int[] P = new int[N+1];
for (int i = 0; i < N; ++i)
P[i+1] = P[i] + A[i];
int[] count = new int[K];
for (int x: P)
count[(x % K + K) % K]++;
int ans = 0;
for (int v: count)
ans += v * (v - 1) / 2;
return ans;
}
}
Complexity Analysis
Time Complexity: , where is the length of
A
.Space Complexity: . (However, the solution can be modified to use space by storing only
count
.)
No comments:
Post a Comment