04. Subarrays With At Most K Distinct Integers
β GFG solution to the Subarrays With At Most K Distinct Integers problem: count subarrays containing at most k distinct elements using sliding window technique. π
The problem can be found at the following link: π Question Link
π§© Problem Description
You are given an array arr[]
of positive integers and an integer k
. Your task is to find the number of subarrays in arr[]
where the count of distinct integers is at most k.
A subarray is a contiguous part of an array. The goal is to efficiently count all valid subarrays without generating them explicitly.
π Examples
Example 1
Input: arr[] = [1, 2, 2, 3], k = 2
Output: 9
Explanation: Subarrays with at most 2 distinct elements are: [1], [2], [2], [3], [1, 2], [2, 2], [2, 3], [1, 2, 2] and [2, 2, 3].
Example 2
Input: arr[] = [1, 1, 1], k = 1
Output: 6
Explanation: Subarrays with at most 1 distinct element are: [1], [1], [1], [1, 1], [1, 1] and [1, 1, 1].
Example 3
Input: arr[] = [1, 2, 1, 1, 3, 3, 4, 2, 1], k = 2
Output: 24
Explanation: There are 24 subarrays with at most 2 distinct elements.
π Constraints
$1 \le \text{arr.size()} \le 2 \times 10^4$
$1 \le k \le 2 \times 10^4$
$1 \le \text{arr}[i] \le 10^9$
β
My Approach
The optimal approach uses the Sliding Window technique with a Hash Map to efficiently count subarrays with at most k distinct elements:
Sliding Window + Hash Map
Initialize Variables:
Use two pointers:
left
(start of window) andright
(end of window).Maintain a hash map to store frequency of elements in current window.
Use a counter to track distinct elements efficiently.
Expand Window:
Move
right
pointer and addarr[right]
to the hash map.If it's a new element (frequency becomes 1), decrement
k
.
Contract Window:
If
k
becomes negative (more than k distinct elements), shrink window from left.Remove
arr[left]
from frequency map and incrementk
if element is completely removed.Move
left
pointer forward.
Count Subarrays:
For each valid window ending at
right
, add(right - left + 1)
to result.This counts all subarrays ending at
right
with at most k distinct elements.
Continue Until End:
Repeat until
right
pointer reaches the end of array.
π Time and Auxiliary Space Complexity
Expected Time Complexity: O(n), where n is the size of the array. Each element is visited at most twice by the sliding window pointers, making it linear time.
Expected Auxiliary Space Complexity: O(k), where k is the maximum number of distinct elements allowed. In the worst case, the hash map stores at most k distinct elements with their frequencies.
π§βπ» Code (C++)
class Solution {
public:
int countAtMostK(vector<int> &arr, int k) {
int n = arr.size(), res = 0, left = 0;
unordered_map<int, int> freq;
for (int right = 0; right < n; right++) {
if (freq[arr[right]]++ == 0) k--;
while (k < 0) {
if (--freq[arr[left]] == 0) k++;
left++;
}
res += right - left + 1;
}
return res;
}
};
π§βπ» Code (Java)
class Solution {
public int countAtMostK(int arr[], int k) {
HashMap<Integer, Integer> freq = new HashMap<>();
int n = arr.length, res = 0, left = 0;
for (int right = 0; right < n; right++) {
freq.put(arr[right], freq.getOrDefault(arr[right], 0) + 1);
while (freq.size() > k) {
freq.put(arr[left], freq.get(arr[left]) - 1);
if (freq.get(arr[left]) == 0) freq.remove(arr[left]);
left++;
}
res += right - left + 1;
}
return res;
}
}
π Code (Python)
class Solution:
def countAtMostK(self, arr, k):
freq = {}
n, res, left = len(arr), 0, 0
for right in range(n):
freq[arr[right]] = freq.get(arr[right], 0) + 1
while len(freq) > k:
freq[arr[left]] -= 1
if freq[arr[left]] == 0:
del freq[arr[left]]
left += 1
res += right - left + 1
return res
π§ Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: π¬ Any Questions?. Let's make this learning journey more collaborative!
β If you find this helpful, please give this repository a star! β
πVisitor Count
Last updated