Skip to content

Commit 1830849

Browse files
committed
Added Count Distinct Subarrays Divisible by K (LeetCode) solution with explanation and test cases
1 parent 09c5814 commit 1830849

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
Problem Name: Count Distinct Subarrays Divisible by K in Sorted Array
3+
Problem Link: https://leetcode.com/problems/count-distinct-subarrays-divisible-by-k-in-sorted-array/
4+
Platform: LeetCode
5+
Language: C++
6+
Author: Aditya Shimoga
7+
Date: 30th October 2025
8+
9+
Description:
10+
-----------------------------------
11+
Given a sorted array nums and an integer k, find the number of distinct subarrays
12+
whose sum is divisible by k.
13+
14+
Key Insight:
15+
-----------------------------------
16+
- For any subarray [l, r], sum(l..r) is divisible by k ⇔ prefixSum[r] % k == prefixSum[l-1] % k.
17+
- To count valid subarrays efficiently, we maintain a frequency map of prefix sums modulo k.
18+
- Since the array is sorted and may contain repeated elements, we process contiguous "blocks"
19+
of equal numbers separately. This ensures we don’t count identical subarrays multiple times.
20+
- For each block:
21+
1. Calculate all valid subarrays ending in this block using prefix remainders from previous blocks.
22+
2. Update the remainder frequency map after processing the block.
23+
24+
Complexity:
25+
-----------------------------------
26+
Time Complexity: O(N)
27+
Space Complexity: O(K) , depending on distinct remainders
28+
*/
29+
30+
#include <bits/stdc++.h>
31+
using namespace std;
32+
33+
class Solution {
34+
public:
35+
long long numGoodSubarrays(vector<int>& nums, int k) {
36+
long long divisor = 1LL * k;
37+
long long prefixSum = 0LL, resultCount = 0LL;
38+
int n = nums.size();
39+
40+
map<int, int> remainderFreq; // Tracks frequency of prefix sums modulo k
41+
42+
int i = 0;
43+
while (i < n) {
44+
int j = i;
45+
int currentValue = nums[i];
46+
long long tempPrefixSum = prefixSum;
47+
48+
// Step 1: Count valid subarrays ending within the current block
49+
while (j < n && nums[j] == currentValue) {
50+
prefixSum += nums[j];
51+
int remainder = prefixSum % divisor;
52+
53+
// Subarray from start (remainder == 0)
54+
if (remainder == 0) resultCount++;
55+
56+
// Subarray ending here matches an earlier prefix remainder
57+
if (remainderFreq.count(remainder))
58+
resultCount += 1LL * remainderFreq[remainder];
59+
60+
j++;
61+
}
62+
63+
// Step 2: Update frequency map for this block
64+
j = i;
65+
while (j < n && nums[j] == currentValue) {
66+
tempPrefixSum += nums[j];
67+
int remainder = tempPrefixSum % divisor;
68+
remainderFreq[remainder]++;
69+
j++;
70+
}
71+
72+
// Move to next distinct value block
73+
i = j;
74+
}
75+
76+
return resultCount;
77+
}
78+
};
79+
80+
/*
81+
Example:
82+
Input:
83+
nums = [1,1,2,2,3], k = 3
84+
85+
Output:
86+
Number of distinct subarrays divisible by 3 = 4
87+
88+
Explanation:
89+
Subarrays divisible 3: [3], [1,2], [1,1,2,2],[1,1,2,2,3]
90+
*/
91+
92+
int main() {
93+
Solution solver;
94+
95+
// Test Case 1
96+
vector<int> nums1 = {1, 1, 2, 2, 3};
97+
int k1 = 3;
98+
long long result1 = solver.numGoodSubarrays(nums1, k1);
99+
cout << "Test Case 1:" << endl;
100+
cout << "Input: nums = [1,1,2,2,3], k = 3" << endl;
101+
cout << "Output: " << result1 << endl;
102+
cout << "Expected: 4" << endl << endl;
103+
104+
// Test Case 2
105+
vector<int> nums2 = {2, 2, 2, 4, 4};
106+
int k2 = 4;
107+
long long result2 = solver.numGoodSubarrays(nums2, k2);
108+
cout << "Test Case 2:" << endl;
109+
cout << "Input: nums = [2,2,2,4,4], k = 4" << endl;
110+
cout << "Output: " << result2 << endl;
111+
cout << "Expected: 6" << endl;
112+
113+
return 0;
114+
}

0 commit comments

Comments
 (0)