hard Subarrays with K Different Integers
Problem Statement
Given an array of integers nums and an integer k, return the number of subarrays with exactly k different integers.
A subarray is a contiguous part of an array.
Examples
Example 1:
- Input:
nums = [4, 2, 4, 2, 5],k = 2 - Output:
7 - Explanation: The subarrays with exactly 2 different integers are
[4, 2],[2, 4],[4, 2, 4],[2, 4, 2],[4, 2],[4, 2, 4, 2], and[2, 5].
Example 2:
- Input:
nums = [2, 4, 1, 3, 1, 3],k = 3 - Output:
4 - Explanation: The subarrays with exactly 3 different integers are
[2, 4, 1],[4, 1, 3],[4, 1, 3, 1], and[4, 1, 3, 1, 3].
Example 3:
- Input:
nums = [4, 4, 4, 5, 5, 6],k = 1 - Output:
10 - Explanation: The subarrays with exactly 1 different integer are
[4],[4],[4],[4, 4],[4, 4],[4, 4, 4],[5],[5],[5, 5]and[6].
Constraints:
- 1 <= nums.length <= 2 * 104
- 1 <= nums[i], k <= nums.length
Try it yourself
Try solving this question here:
🎯 STRICT STANDOUT — Subarrays with K Different Integers — problem
1. Why / judgment
Exactly-K is hard to maintain as a single window invariant. Standard reduction: number of subarrays with at most K distinct is easy with two pointers + freq map; then exactly K = atMost(K) − atMost(K−1). Recognition: “exactly K different” almost always means this difference of two window counts.
2. Big-O derivation (K11)
n≤2e4.
atMost: each pointer moves ≤n → O(n) per call, two calls → O(n).
Space O(n) map/array of freqs.
Brute O(n²) distinct checks too slow.
3. Pattern + when-NOT (K12)
Name: AT-MOST WINDOW DIFFERENCE (exactly-K distinct)
Recognition: count subarrays with exactly K distinct integers.
When-NOT: Need longest with ≤K → single window, not difference. Need sum of distinct counts → different formula. Non-contiguous subsequences → not sliding window.
4. Edge hand-run (K13)
nums=[4,2,4,2,5] k=2 → 7 (statement).
k=1 → count runs of equal? more generally atMost1−atMost0.
k > distinct(all) → 0.
5. Interviewer follow-ups (model answers)
Q1. Why not one window that keeps exactly K?
A: Multiple valid left bounds for one right; “exactly” shrinks/grows ambiguously. atMost cleanly counts all good ends.
Q2. Map vs count array?
A: If values ≤n you can remap; else HashMap. Values here positive ≤n often → array ok after compression.
Q3. Related hard problems?
A: Longest substring with K distinct; fruit into baskets (K=2); replace pattern with “exactly K odd” etc.
6. Short drills
Drill: [4,4,4,5,5,6] k=1 → 10.
Drill: write atMost pseudocode from memory.
✅ Solution Subarrays with K Different Integers
Problem Statement
Given an array of integers nums and an integer k, return the number of subarrays with exactly k different integers.
A subarray is a contiguous part of an array.
Examples
Example 1:
- Input:
nums = [4, 2, 4, 2, 5],k = 2 - Output:
7 - Explanation: The subarrays with exactly 2 different integers are
[4, 2],[2, 4],[4, 2, 4],[2, 4, 2],[4, 2],[4, 2, 4, 2], and[2, 5].
Example 2:
- Input:
nums = [2, 4, 1, 3, 1, 3],k = 3 - Output:
4 - Explanation: The subarrays with exactly 3 different integers are
[2, 4, 1],[4, 1, 3],[4, 1, 3, 1], and[4, 1, 3, 1, 3].
Example 3:
- Input:
nums = [4, 4, 4, 5, 5, 6],k = 1 - Output:
10 - Explanation: The subarrays with exactly 1 different integer are
[4],[4],[4],[4, 4],[4, 4],[4, 4, 4],[5],[5],[5, 5]and[6].
Constraints:
- 1 <= nums.length <= 2 * 104
- 1 <= nums[i], k <= nums.length
Solution
To solve this problem, we use a sliding window approach combined with a count array. The idea is to maintain a window that slides over the array while keeping track of the number of distinct integers in the window. By adjusting the window size dynamically, we can count the number of subarrays with exactly k distinct integers.
This method is efficient because it processes each element in the array once, making it linear in time complexity. The count array helps in tracking the frequency of each integer within the window, allowing us to efficiently manage the window boundaries.
Step-by-Step Algorithm
-
Initialization:
- Create an array
countof sizenums.length + 1to store the frequency of each element in the current window. - Initialize
resultto store the total number of subarrays with exactlykdistinct integers. - Set
leftandrightpointers to the start of the array. - Initialize
windowCountto keep track of valid subarrays within the current window.
- Create an array
-
Expand the window:
- While
rightis less than the length ofnums, do the following:- Increment the count for the element at the
rightpointer and move therightpointer to the right. - If the element at
rightwas not in the window before (its count was zero), decrementk.
- Increment the count for the element at the
- While
-
Adjust the window:
- If
kbecomes negative, it means the window has more thankdistinct elements:- Move the
leftpointer to the right until the window has exactlykdistinct elements again, decrementing the count of the element at theleftpointer each time and incrementingk. - Reset
windowCountto zero.
- Move the
- If
-
Count valid subarrays:
- If
kis zero, it means the window has exactlykdistinct elements:- Move the
leftpointer to the right while the count of the element atleftis greater than one, reducing the window size. - For each valid adjustment, increment
windowCount. - Add
windowCount + 1toresult.
- Move the
- If
-
Return the result:
- The final value of
resultis the number of subarrays with exactlykdistinct integers.
- The final value of
Algorithm Walkthrough
Let's walk through the algorithm step-by-step with the input nums = [4, 2, 4, 2, 5] and k = 2.
-
Initialization:
count = [0, 0, 0, 0, 0, 0]result = 0left = 0right = 0windowCount = 0
-
First iteration (right = 0):
- Increment
count[4]→count = [0, 0, 0, 0, 1, 0] - Move
rightto 1 kbecomes 1
- Increment
-
Second iteration (right = 1):
- Increment
count[2]→count = [0, 0, 1, 0, 1, 0] - Move
rightto 2 kbecomes 0- Count subarrays:
count[nums[0]] = count[0](0) > 1is false, so no change inleftwindowCount = 0- Add
windowCount + 1toresult→result = 1
- Increment
-
Third iteration (right = 2):
- Increment
count[4]→count = [0, 0, 1, 0, 2, 0] - Move
rightto 3 kis already0.- Count subarrays:
count[nums[0]] = count[0](1) > 1is true, decrementcount[4]and moveleftto 1 →count = [0, 0, 1, 0, 1, 0]windowCount = 1- Add
windowCount + 1toresult→result = 3
- Increment
-
Fourth iteration (right = 3):
- Increment
count[2]→count = [0, 0, 2, 0, 1, 0] - Move
rightto 4 kis already0.- Count subarrays:
count[nums[1]] = count[2](2) > 1is true, decrementcount[2]and moveleftto 2 →count = [0, 0, 1, 0, 1, 0]windowCount = 2- Add
windowCount + 1toresult→result = 6
- Increment
-
Fifth iteration (right = 4):
- Increment
count[5]→count = [0, 0, 1, 0, 1, 1] - Move
rightto 5 kbecomes -1 (more thankdistinct elements)- Adjust the window:
- Decrement
count[4]and moveleftto 3 →count = [0, 0, 1, 0, 0, 1] kbecomes 0windowCount = 0count[nums[3] = count[2](1) > 1is false- Add
windowCount + 1toresult→result = 7
- Decrement
- Increment
The final result is 7, indicating there are 7 subarrays with exactly 2 distinct integers.
Code
public class Solution {
public int subarraysWithKDistinct(int[] nums, int k) {
// Array to count distinct values in the current window
int[] count = new int[nums.length + 1];
int result = 0; // Total number of subarrays with exactly k distinct integers
int left = 0; // Left boundary of the window
int right = 0; // Right boundary of the window
int windowCount = 0; // Current number of valid subarrays in the window
while (right < nums.length) {
// Increase the count for the current element and move the right boundary
if (count[nums[right++]]++ == 0) {
// If this is a new distinct element, decrement k
k--;
}
// If there are more than k distinct elements, adjust the window from the left
if (k < 0) {
// Reduce the count for the element at the left boundary and move the left boundary
--count[nums[left++]];
k++;
windowCount = 0;
}
// If there are exactly k distinct elements, count the subarrays
if (k == 0) {
// Move the left boundary to reduce the window size while maintaining k distinct elements
while (count[nums[left]] > 1) {
--count[nums[left++]];
windowCount++;
}
// Add the current number of valid subarrays to the result
result += (windowCount + 1);
}
}
return result;
}
public static void main(String[] args) {
Solution solution = new Solution();
// Example 1
int[] nums1 = { 4, 2, 4, 2, 5 };
int k1 = 2;
System.out.println(solution.subarraysWithKDistinct(nums1, k1)); // Output: 7
// Example 2
int[] nums2 = { 2, 4, 1, 3, 1, 3 };
int k2 = 3;
System.out.println(solution.subarraysWithKDistinct(nums2, k2)); // Output: 4
// Example 3
int[] nums3 = { 4, 4, 4, 5, 5, 6 };
int k3 = 1;
System.out.println(solution.subarraysWithKDistinct(nums3, k3)); // Output: 10
}
}
Complexity Analysis
Time Complexity
The algorithm operates in linear time relative to the input size. This is due to the following reasons:
- Both the
rightandleftpointers move from the start to the end of the array, resulting in an overalltime complexity, where nis the length of the input arraynums.
Space Complexity
The space complexity is count array which stores the frequency of each element in the window. The size of the count array is proportional to the length of nums.
🎯 STRICT STANDOUT — Solution Subarrays with K Different Integers
1. Why / judgment
atMost(limit): for right in 0..n-1 add nums[right]; while distinct>limit remove nums[left]. All windows ending at right with left' in [left,right] are valid → add (right-left+1). Return atMost(k)-atMost(k-1).
2. Big-O derivation (K11)
[4,2,4,2,5] k=2:
atMost(2): subarrays with ≤2 distinct.
atMost(1): only mono-value windows.
Difference = 7 ✓ (matches enumeration).
[2,4,1,3,1,3] k=3 → 4 ✓
Time: 2 × O(n). Each index enters/leaves window once per atMost.
3. Pattern + when-NOT (K12)
Name: TWO SLIDING WINDOWS / FREQ MAP
Recognition: exactly K via difference of at-most counts.
When-NOT: k=0 edge: atMost(-1) must return 0.
4. Edge hand-run (K13)
All equal, k=1 → n(n+1)/2.
All equal, k=2 → 0.
Single element k=1 → 1.
5. Interviewer follow-ups (model answers)
Q1. Derive right-left+1
A: After shrink, window [left,right] has ≤K distinct; every subarray ending at right starting at s∈[left,right] also has ≤K (subset of multiset).
Q2. Why amortized O(n)?
A: left only increases; total left moves ≤ n; right moves n.
Q3. Can monoqueue replace map?
A: No — need distinct cardinality, not min/max. Freq map/set is the right structure.
6. Short drills
Drill: recompute example k=3 → 4 offline.
Drill: implement and test k=0 → 0.
Recognize it: Membership / frequency / “have I seen this?” in O(1) → a hash map or set.
▶ Visualize this problem (step it, predict each fork)
🤖 Don't fully get this? Learn it with Claude
Stuck on Subarrays with K Different Integers? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Progressively stronger hints — you still solve it.
I'm working on the problem **Subarrays with K Different Integers** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
See the technique, not just code.
Explain the optimal approach to **Subarrays with K Different Integers** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Catch bugs, edge cases, sub-optimality.
I'll paste my solution to **Subarrays with K Different Integers**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Lock in recognition with look-alikes.
Give me 2 problems that use the SAME underlying pattern as **Subarrays with K Different Integers**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.