Given an array of integers nums
and an integer k
. A continuous subarray is called nice if there are k
odd numbers in it.
Return the number of nice sub-arrays.
Example 1:
Input: nums = [1,1,2,1,1], k = 3
Output: 2
Explanation: The only sub-arrays with 3 odd numbers are [1,1,2,1] and [1,2,1,1].
Example 2:
Input: nums = [2,4,6], k = 1
Output: 0
Explanation: There are no odd numbers in the array.
Example 3:
Input: nums = [2,2,2,1,2,2,1,2,2,2], k = 2
Output: 16
Constraints:
1 <= nums.length <= 50000
1 <= nums[i] <= 10^5
1 <= 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 find nice subarrays involves checking every single possible subarray within the given list of numbers. For each subarray, we'll count the number of odd numbers it contains and see if that count matches our target. We'll repeat this process for every possible subarray and count how many meet the criteria.
Here's how the algorithm would work step-by-step:
def count_number_of_nice_subarrays_brute_force(numbers, target):
number_of_nice_subarrays = 0
for start_index in range(len(numbers)):
for end_index in range(start_index, len(numbers)):
current_subarray = numbers[start_index:end_index+1]
odd_count = 0
# Iterate through the subarray and count odd numbers
for number in current_subarray:
if number % 2 != 0:
odd_count += 1
# Check if current subarray is "nice"
if odd_count == target:
number_of_nice_subarrays += 1
return number_of_nice_subarrays
Instead of checking every possible group of numbers, the optimal approach cleverly focuses on counting the number of valid groups as it moves through the numbers one by one. It tracks how many groups ending at each position meet the requirement of having a specific number of odd numbers.
Here's how the algorithm would work step-by-step:
def count_number_of_nice_subarrays(numbers, target):
odd_count_so_far = 0
nice_subarrays_count = 0
# Store frequency of odd number counts seen.
odd_counts = {0: 1}
for number in numbers:
if number % 2 != 0:
odd_count_so_far += 1
# Determine needed prior odd count.
needed_odd_count = odd_count_so_far - target
# Add subarrays ending here if a prior count exists
if needed_odd_count in odd_counts:
nice_subarrays_count += odd_counts[needed_odd_count]
# Update the frequency of the current odd number count
if odd_count_so_far in odd_counts:
odd_counts[odd_count_so_far] += 1
else:
odd_counts[odd_count_so_far] = 1
return nice_subarrays_count
Case | How to Handle |
---|---|
Null or empty input array | Return 0, as there are no subarrays in an empty array. |
k is zero | Count subarrays with only even numbers, which can be done with sliding window. |
k is greater than the number of odd numbers in the array | Return 0, as it's impossible to have k odd numbers in a subarray. |
Array contains only even numbers and k > 0 | Return 0, because no subarray can have odd numbers. |
Large input array size and potentially many nice subarrays - scalability | Prefix sum and hash map approach is preferred for better time complexity. |
Integer overflow if counting very large number of subarrays | Use appropriate data types (e.g., long) for counting subarrays. |
Array contains negative numbers | The sign of numbers does not affect the odd/even determination, so treat them the same as positive numbers. |
Array contains zero values | Zeros are even numbers and do not impact the count of odd numbers. |