Given an integer array nums
and an integer k
, return the number of good subarrays of nums
.
A good array is an array where the number of different integers in that array is exactly k
.
[1,2,3,1,2]
has 3
different integers: 1
, 2
, and 3
.A subarray is a contiguous part of an array.
Example 1:
Input: nums = [1,2,1,2,3], k = 2
Output: 7
Explanation: Subarrays formed with exactly 2 different integers: [1,2], [2,1], [1,2], [2,3], [1,2,1], [2,1,2], [1,2,1,2]
Example 2:
Input: nums = [1,2,1,3,4], k = 3
Output: 3
Explanation: Subarrays formed with exactly 3 different integers: [1,2,1,3], [2,1,3], [1,3,4].
Constraints:
1 <= nums.length <= 2 * 10^4
1 <= nums[i], k <= nums.length
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method to solve this problem is simple: we will consider every possible group of numbers within the given list. For each of these groups, we check if it fulfills the requirement of having exactly K distinct numbers.
Here's how the algorithm would work step-by-step:
def subarrays_with_k_distinct_integers_brute_force(numbers, k_distinct):
number_of_valid_subarrays = 0
for start_index in range(len(numbers)):
for end_index in range(start_index, len(numbers)):
sub_array = numbers[start_index:end_index + 1]
# To count the distinct numbers in the subarray.
distinct_numbers = set()
for number in sub_array:
distinct_numbers.add(number)
# Check if the current subarray has exactly k distinct integers
if len(distinct_numbers) == k_distinct:
# Only increment counter when sub array has correct number of distinct values
number_of_valid_subarrays += 1
return number_of_valid_subarrays
The most efficient way to count subarrays with exactly K distinct integers involves using a clever sliding window approach. Instead of brute-force checking all subarrays, we use inclusion-exclusion to count subarrays with at most K distinct integers minus those with at most K-1 distinct integers.
Here's how the algorithm would work step-by-step:
def subarraysWithKDistinct(nums, k):
def atMostK(nums, k):
if k < 0:
return 0
window_start = 0
window_end = 0
distinct_count = 0
frequency_map = {}
result = 0
while window_end < len(nums):
right_element = nums[window_end]
if right_element not in frequency_map:
frequency_map[right_element] = 0
distinct_count += 1
frequency_map[right_element] += 1
# Shrink the window if distinct count exceeds k.
while distinct_count > k:
left_element = nums[window_start]
frequency_map[left_element] -= 1
if frequency_map[left_element] == 0:
del frequency_map[left_element]
distinct_count -= 1
window_start += 1
# Add the number of valid subarrays ending at window_end.
result += window_end - window_start + 1
window_end += 1
return result
# Inclusion-exclusion principle.
return atMostK(nums, k) - atMostK(nums, k - 1)
Case | How to Handle |
---|---|
Null or empty input array | Return 0 immediately, as no subarrays exist. |
k = 0 | Return 0, as a subarray must have at least one distinct integer. |
k is greater than the number of distinct elements in the input array | The maximum number of distinct elements possible is the number of distinct elements in the array, so the result will be the same if k exceeds the number of distinct elements, which the sliding window algorithm naturally handles. |
Array contains only one distinct element, and k > 1 | Return 0, as it's impossible to find a subarray with more than one distinct element when the input array has only one. |
Array contains duplicate numbers, and k = 1 | The solution should correctly count all subarrays with only the repeated number. |
Large array size with a small k value | Sliding window approach handles this efficiently, adjusting window size as required. |
Integer overflow potential during window size calculation with large array indices | Ensure calculations use appropriate data types (e.g., long) to prevent overflow. |
Array contains negative numbers | The hashmap approach works fine since numbers are stored as keys, allowing for negative and zero input. |