Sale: Get 60% Off on all Pro Plans. Buy Now

Subarrays with K Different Integers

Problem

Given an integer array nums and an integer k, return the number of subarrays with exactly k distinct integers.

  • 1 ≤ nums.length ≤ 2 * 10⁴
  • 1 ≤ nums[i], k ≤ nums.length

Example

Input: nums = [1,2,1,2,3], k = 2
Output: 7

The subarrays with exactly 2 distinct integers are: [1,2], [2,1], [1,2], [2,3], [1,2,1], [2,1,2], and [1,2,1,2]. The algorithm uses a helper function to count subarrays with at most k distinct integers and subtracts the count of subarrays with at most k-1 distinct integers to get the exact count. For k=2, atMost(2) counts all subarrays with up to 2 distinct integers, and atMost(1) counts those with up to 1 distinct integer. Their difference yields the count of subarrays with exactly 2 distinct integers.

Approach

Straightforward Solution

A brute-force approach would enumerate all subarrays and count distinct integers in each, resulting in O(n^2) or worse time complexity, which is too slow for large inputs.

Core Observation

The number of subarrays with exactly k distinct integers equals the number of subarrays with at most k distinct integers minus the number of subarrays with at most k-1 distinct integers. This transforms the problem into counting subarrays with at most k distinct integers, which can be efficiently done using a sliding window.

Path to Optimal

Preview

The key insight is to use the sliding window technique to count subarrays with at most k distinct integers in O(n) time…

Full step-by-step walkthrough on Pro

Optimal Approach

Preview

Implement a helper function atMost(k) that uses a sliding window to count subarrays with at most k distinct integers. The main function returns atMost(k) - atMost(k - 1)…

Full step-by-step walkthrough on Pro

Want the full reasoning chain?

Unlock the complete walkthrough, line-by-line analysis, and recall drill.

Unlock Pro

Time

O(n)

Each element is visited at most twice: once when expanding the right pointer and once when moving the left pointer. The frequency map operations are O(1) on average, resulting in an overall linear time complexity.

Space

O(n)

The frequency map stores counts of elements currently in the sliding window. In the worst case, it can hold all distinct elements in nums, which is O(n). This auxiliary space is necessary to track distinct counts efficiently.

Pattern Spotlight

Sliding Window (Counting Subarrays with Constraints)

When counting subarrays with an exact number of distinct elements, transform the problem into the difference of counts of subarrays with at most k and at most k-1 distinct elements, enabling efficient linear-time sliding window solutions.

Solution

Python
1class Solution:
2 def subarraysWithKDistinct(self, nums, k):
3
4 def atMost(k):
5 count = {}
6 left = 0
7 res = 0
8
9 for right, n in enumerate(nums):
10
11 count[n] = count.get(n, 0) + 1
12
13 while len(count) > k:
14 count[nums[left]] -= 1
15
16 if count[nums[left]] == 0:
17 del count[nums[left]]
18
19 left += 1
20
21 res += right - left + 1
22
23 return res
24
25 return atMost(k) - atMost(k - 1)

Step-by-Step Solution

1

Count Subarrays with At Most K Distinct Integers Using Sliding Window

4def atMost(k):
5 count = {}
6 left = 0
7 res = 0
9 for right, n in enumerate(nums):
11 count[n] = count.get(n, 0) + 1
13 while len(count) > k:
14 count[nums[left]] -= 1
16 if count[nums[left]] == 0:
17 del count[nums[left]]
19 left += 1
21 res += right - left + 1
23 return res

Objective

To count the number of subarrays with at most k distinct integers by expanding and contracting a sliding window.

Key Insight

The sliding window maintains a frequency map of elements within the window and adjusts its left boundary to ensure the window contains at most k distinct integers. For each right pointer position, the number of valid subarrays ending at that position is the window size (right - left + 1). Summing these counts yields the total number of subarrays with at most k distinct integers. This approach avoids enumerating all subarrays explicitly, achieving linear time complexity.

Interview Quick-Check

Core Logic

The sliding window expands the right pointer and contracts the left pointer to maintain at most k distinct integers, counting valid subarrays by window size at each step.

State & Boundaries

The while loop condition ensures the window never exceeds k distinct integers by removing elements from the left until the constraint is satisfied.

Common Pitfalls & Bugs

Forgetting to delete keys from the frequency map when their count drops to zero can cause incorrect distinct counts and infinite loops.

Complexity

Each element is added and removed from the frequency map at most once, ensuring O(n) time complexity.

2

Calculate Exact Count by Subtracting Counts of At Most K and K-1

To compute the number of subarrays with exactly k distinct integers by subtracting counts of subarrays with at most k-1 distinct integers from those with at most k.

1 more step with full analysis available on Pro.

Line Analysis

This solution has 4 Critical lines interviewers watch for.

Line 25 Critical
return atMost(k) - atMost(k - 1)

Return the difference between counts of subarrays with at most k and at most k-1 distinct integers.

This subtraction isolates the count of subarrays with exactly k distinct integers, leveraging the helper function's results and the inclusion-exclusion principle.

Line 13 Critical
while len(count) > k:

While the window contains more than k distinct integers, shrink it from the left.

This loop enforces the constraint of at most k distinct integers by moving the left pointer forward and updating frequencies accordingly.

Line 17 Critical
del count[nums[left]]

Delete the element from the frequency map so the distinct count remains accurate.

Removing elements whose count becomes zero ensures the dictionary size accurately represents the number of distinct elements in the window, which is required for the len(count) constraint check.

Full line-by-line criticality + rationale for all 14 lines available on Pro.

Test Your Understanding

Why does subtracting the count of subarrays with at most k-1 distinct integers from the count of subarrays with at most k distinct integers yield the count of subarrays with exactly k distinct integers?

See the answer with Pro.

Related Problems

Sliding Window pattern

Don't just read it. Drill it.

Reconstruct Subarrays with K Different Integers from memory until it sticks. AlgoDrill blanks out key lines and makes you fill them back in, step by step.

Unlock the Subarrays with K Different Integers drill

or drill a free problem