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:
✅ 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.
🤖 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.