Count Subarrays With Exactly K Distinct Elements
Last Updated :
08 Jan, 2025
Given an array arr[] and an integer k, the task is to find the count of subarrays such that each subarray has exactly k distinct elements.
Examples:
Input: arr[] = [1, 2, 2, 3], k = 2
Output: 4
Explanation: Subarrays with exactly 2 distinct elements are: [1, 2], [1, 2, 2] and [2, 3].
Input: arr[] = [3, 1, 2, 2, 3], k = 3
Output: 4
Explanation: Subarrays with exactly 3 distinct elements are: [3, 1, 2], [3, 1, 2, 2], [3, 1, 2, 2, 3] and [1, 2, 2, 3].
Input: arr[] = [1, 1, 1, 1], k = 2
Output: 0
Explanation: There is no subarray having exactly 2 distinct integers.
[Naive Approach] Exploring all subarrays - O(n^2) Time and O(n) Space
The idea is to iterate over all possible subarrays while keeping the count of distinct integers using a hash set. For every subarray, check if the size of hash set is equal to k. If the size of hash set equals k, increment the result by 1. After iterating over all subarrays, return the result.
C++
// C++ Code to count the subarrays having exactly
// k distinct elements by exploring all subarrays
#include <iostream>
#include <unordered_set>
#include <vector>
using namespace std;
int exactlyK(vector<int> &arr, int k) {
int n = arr.size();
int res = 0;
// Iterate over all subarrays arr[i...j]
for (int i = 0; i < n; i++) {
// hash set to count distinct elements
unordered_set<int> st;
for (int j = i; j < n; j++) {
st.insert(arr[j]);
// If count of distinct elements > k, then
// don't extend the subarray further
if (st.size() > k)
break;
if (st.size() == k)
res += 1;
}
}
return res;
}
int main() {
vector<int> arr = {1, 2, 2, 3};
int k = 2;
cout << exactlyK(arr, k);
}
Java
// Java Code to count the subarrays having exactly
// k distinct elements by exploring all subarrays
import java.util.HashSet;
class GfG {
static int exactlyK(int[] arr, int k) {
int n = arr.length;
int res = 0;
// Iterate over all subarrays arr[i...j]
for (int i = 0; i < n; i++) {
// Hash set to count distinct elements
HashSet<Integer> st = new HashSet<>();
for (int j = i; j < n; j++) {
st.add(arr[j]);
// If count of distinct elements > k, then
// don't extend the subarray further
if (st.size() > k)
break;
if (st.size() == k)
res += 1;
}
}
return res;
}
public static void main(String[] args) {
int[] arr = {1, 2, 2, 3};
int k = 2;
System.out.println(exactlyK(arr, k));
}
}
Python
# Python Code to count the subarrays having exactly
# k distinct elements by exploring all subarrays
def exactlyK(arr, k):
n = len(arr)
res = 0
# Iterate over all subarrays arr[i...j]
for i in range(n):
# Set to count distinct elements
st = set()
for j in range(i, n):
st.add(arr[j])
# If count of distinct elements > k, then
# don't extend the subarray further
if len(st) > k:
break
if len(st) == k:
res += 1
return res
if __name__ == "__main__":
arr = [1, 2, 2, 3]
k = 2
print(exactlyK(arr, k))
C#
// C# Code to count the subarrays having exactly
// k distinct elements by exploring all subarrays
using System;
using System.Collections.Generic;
class GfG {
static int ExactlyK(int[] arr, int k) {
int n = arr.Length;
int res = 0;
// Iterate over all subarrays arr[i...j]
for (int i = 0; i < n; i++) {
// HashSet to count distinct elements
HashSet<int> st = new HashSet<int>();
for (int j = i; j < n; j++) {
st.Add(arr[j]);
// If count of distinct elements > k, then
// don't extend the subarray further
if (st.Count > k)
break;
if (st.Count == k)
res += 1;
}
}
return res;
}
static void Main() {
int[] arr = { 1, 2, 2, 3 };
int k = 2;
Console.WriteLine(ExactlyK(arr, k));
}
}
JavaScript
// JavaScript Code to count the subarrays having exactly
// k distinct elements by exploring all subarrays
function exactlyK(arr, k) {
let n = arr.length;
let res = 0;
// Iterate over all subarrays arr[i...j]
for (let i = 0; i < n; i++) {
// Set to count distinct elements
let st = new Set();
for (let j = i; j < n; j++) {
st.add(arr[j]);
// If count of distinct elements > k, then
// don't extend the subarray further
if (st.size > k)
break;
if (st.size === k)
res += 1;
}
}
return res;
}
// Driver Code
let arr = [1, 2, 2, 3];
let k = 2;
console.log(exactlyK(arr, k));
[Expected Approach] Using Sliding Window Technique - O(n) Time and O(n) Space
The idea is similar to the problem Count Subarrays With At Most K Distinct Elements. To find the number of subarrays with exactly k distinct elements, we can use the formula: exactly(k) = atMost(k) - atMost(k - 1).
Count of subarrays with at most k different elements can be easily calculated using sliding window technique. Initialize left = 0 and right = 0 to mark the boundaries of sliding window. Expand the right boundary until distinct element count exceeds k, then shrink the left boundary until the distinct element count becomes <= k. While expanding the window, for each right boundary keep counting the subarrays as (right - left + 1).
The intuition behind (right - left + 1) is that it counts all possible subarrays that end at right and start at any index between left and right. These are valid subarrays because they all contain at most k distinct elements.
C++
// C++ Code to count the subarrays having exactly
// k distinct elements by exploring all subarrays
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
int atMostK(vector<int> &arr, int k) {
int n = arr.size();
int res = 0;
// pointers to mark the left and right boundary
int left = 0, right = 0;
// Frequency map
unordered_map<int, int> freq;
while (right < n) {
freq[arr[right]] += 1;
// If this is a new element in the window,
// decrement k by 1
if (freq[arr[right]] == 1)
k -= 1;
// Shrink the window until distinct element
// count becomes <= k
while (k < 0) {
freq[arr[left]] -= 1;
if (freq[arr[left]] == 0)
k += 1;
left += 1;
}
// add all possible subarrays to result
res += (right - left + 1);
right += 1;
}
return res;
}
int exactlyK(vector<int> &arr, int k) {
return atMostK(arr, k) - atMostK(arr, k - 1);
}
int main() {
vector<int> arr = {1, 2, 2, 3};
int k = 2;
cout << exactlyK(arr, k);
}
Java
// Java Code to count the subarrays having exactly
// k distinct elements by exploring all subarrays
import java.util.HashMap;
import java.util.Map;
class GfG {
// Function to count subarrays having at most k distinct elements
static int atMostK(int[] arr, int k) {
int n = arr.length;
int res = 0;
// pointers to mark the left and right boundary
int left = 0, right = 0;
// Frequency map
Map<Integer, Integer> freq = new HashMap<>();
while (right < n) {
freq.put(arr[right], freq.getOrDefault(arr[right], 0) + 1);
// If this is a new element in the window,
// decrement k by 1
if (freq.get(arr[right]) == 1)
k -= 1;
// Shrink the window until distinct element
// count becomes <= k
while (k < 0) {
freq.put(arr[left], freq.get(arr[left]) - 1);
if (freq.get(arr[left]) == 0)
k += 1;
left += 1;
}
// add all possible subarrays to result
res += (right - left + 1);
right += 1;
}
return res;
}
// Function to count subarrays having exactly k distinct elements
static int exactlyK(int[] arr, int k) {
return atMostK(arr, k) - atMostK(arr, k - 1);
}
public static void main(String[] args) {
int[] arr = {1, 2, 2, 3};
int k = 2;
System.out.println(exactlyK(arr, k));
}
}
Python
# Python Code to count the subarrays having exactly
# k distinct elements by exploring all subarrays
from collections import defaultdict
def atMostK(arr, k):
n = len(arr)
res = 0
# pointers to mark the left and right boundary
left, right = 0, 0
# Frequency map
freq = defaultdict(int)
while right < n:
freq[arr[right]] += 1
# If this is a new element in the window,
# decrement k by 1
if freq[arr[right]] == 1:
k -= 1
# Shrink the window until distinct element
# count becomes <= k
while k < 0:
freq[arr[left]] -= 1
if freq[arr[left]] == 0:
k += 1
left += 1
# add all possible subarrays to result
res += (right - left + 1)
right += 1
return res
# Function to count subarrays having exactly k distinct elements
def exactlyK(arr, k):
return atMostK(arr, k) - atMostK(arr, k - 1)
if __name__ == "__main__":
arr = [1, 2, 2, 3]
k = 2
print(exactlyK(arr, k))
C#
// C# Code to count the subarrays having exactly
// k distinct elements by exploring all subarrays
using System;
using System.Collections.Generic;
class GfG {
static int atMostK(int[] arr, int k) {
int n = arr.Length;
int res = 0;
// pointers to mark the left and right boundary
int left = 0, right = 0;
// Frequency map
Dictionary<int, int> freq = new Dictionary<int, int>();
while (right < n) {
if (freq.ContainsKey(arr[right]))
freq[arr[right]] += 1;
else
freq[arr[right]] = 1;
// If this is a new element in the window,
// decrement k by 1
if (freq[arr[right]] == 1)
k -= 1;
// Shrink the window until distinct element
// count becomes <= k
while (k < 0) {
freq[arr[left]] -= 1;
if (freq[arr[left]] == 0)
k += 1;
left += 1;
}
// add all possible subarrays to result
res += (right - left + 1);
right += 1;
}
return res;
}
// Function to count subarrays having exactly k distinct elements
static int exactlyK(int[] arr, int k) {
return atMostK(arr, k) - atMostK(arr, k - 1);
}
static void Main(string[] args) {
int[] arr = { 1, 2, 2, 3 };
int k = 2;
Console.WriteLine(exactlyK(arr, k));
}
}
JavaScript
// JavaScript Code to count the subarrays having exactly
// k distinct elements by exploring all subarrays
function atMostK(arr, k) {
let n = arr.length;
let res = 0;
// pointers to mark the left and right boundary
let left = 0, right = 0;
// Frequency map
let freq = new Map();
while (right < n) {
freq.set(arr[right], (freq.get(arr[right]) || 0) + 1);
// If this is a new element in the window,
// decrement k by 1
if (freq.get(arr[right]) === 1)
k -= 1;
// Shrink the window until distinct element
// count becomes <= k
while (k < 0) {
freq.set(arr[left], freq.get(arr[left]) - 1);
if (freq.get(arr[left]) === 0)
k += 1;
left += 1;
}
// add all possible subarrays to result
res += (right - left + 1);
right += 1;
}
return res;
}
// Function to count subarrays having exactly k distinct elements
function exactlyK(arr, k) {
return atMostK(arr, k) - atMostK(arr, k - 1);
}
// Driver Code
let arr = [1, 2, 2, 3];
let k = 2;
console.log(exactlyK(arr, k));
Count Subarrays With Exactly K Distinct Elements
Visit Course
Similar Reads
Count Subarrays With At Most K Distinct Elements Given an array arr[] of integers and a positive integer k, the goal is to count the total number of subarrays that contain at most k distinct (unique) elements.Examples:Input: arr[] = [1, 2, 2, 3], k = 2 Output: 9Explanation: Subarrays with at most 2 distinct elements are: [1], [2], [2], [3], [1, 2]
9 min read
Count of Subsequences with distinct elements Given an array arr[] (1<=a[i]<=1e9) containing N (1<=N<=1e5) elements, the task is to find the total number of subsequences such that all elements in that subsequences are distinct. Since the answer can be very large print and modulo 1e9+7. Examples: Input: arr[] = [1, 1, 2, 2]Output: 8E
5 min read
Construct an Array having K Subarrays with all distinct elements Given integers N and K, the task is to construct an array arr[] of size N using numbers in the range [1, N] such that it has K sub-arrays whose all the elements are distinct. Note: If there are multiple possible answers return any of them. Examples: Input: N = 5, K = 8Output: {1, 2, 3, 3, 3}Explanat
7 min read
Count subarrays with all elements greater than K Given an array of n integers and an integer k, the task is to find the number of subarrays such that all elements in each subarray are greater than k.Examples: Input: arr[] = {3, 4, 5, 6, 7, 2, 10, 11}, k= 5 Output: 6 The possible subarrays are {6}, {7}, {6, 7}, {10}, {11} and {10, 11}.Input: arr[]
9 min read
Count subarrays having at least X distinct elements that occur exactly Y times Given three integers N, X, Y, and an array arr[] of size N, the task is to find the count of subarrays having at least X distinct elements that occur only Y times. Example: Input: N = 9, X = 2, Y = 2, arr[] = {2, 1, 2, 5, 3, 1, 3, 2, 5}Output:10Explanation:Subarrays with at least X distinct elements
8 min read
Count Distinct Elements In Every Window of Size K Given an array arr[] of size n and an integer k, return the count of distinct numbers in all windows of size k. Examples: Input: arr[] = [1, 2, 1, 3, 4, 2, 3], k = 4Output: [3, 4, 4, 3]Explanation: First window is [1, 2, 1, 3], count of distinct numbers is 3. Second window is [2, 1, 3, 4] count of d
10 min read