Given an array of integers nums
and an integer k
. A continuous subarray is called nice if there are k
odd numbers on 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:
To solve this problem the hard way, we're going to examine every single possible group of numbers within the given set. For each group, we'll check if it meets our specific criteria for being 'nice'.
Here's how the algorithm would work step-by-step:
def count_number_nice_subarrays_brute_force(numbers, target_odd_count):
number_of_nice_subarrays = 0
array_length = len(numbers)
for subarray_size in range(1, array_length + 1):
# Iterate through all possible subarrays of the current size
for start_index in range(array_length - subarray_size + 1):
end_index = start_index + subarray_size
subarray = numbers[start_index:end_index]
odd_count = 0
# Count odd numbers in the current subarray
for number in subarray:
if number % 2 != 0:
odd_count += 1
# Check if the current subarray is "nice"
if odd_count == target_odd_count:
# Increment the count if the subarray is nice
number_of_nice_subarrays += 1
return number_of_nice_subarrays
Instead of checking every possible group of numbers, we use a sliding window approach. We expand and shrink the window based on whether the number of odd numbers within that window meets our target.
Here's how the algorithm would work step-by-step:
def count_number_of_nice_subarrays(numbers, target):
number_of_odd_numbers = 0
left_window_boundary = 0
nice_subarray_count = 0
for right_window_boundary in range(len(numbers)):
if numbers[right_window_boundary] % 2 != 0:
number_of_odd_numbers += 1
# Shrink window when odd count exceeds target.
while number_of_odd_numbers > target:
if numbers[left_window_boundary] % 2 != 0:
number_of_odd_numbers -= 1
left_window_boundary += 1
# Count subarrays if odd count equals target.
if number_of_odd_numbers == target:
even_numbers_to_left = 0
temporary_left_boundary = left_window_boundary
# Count leading even numbers to find valid subarrays.
while numbers[temporary_left_boundary] % 2 == 0:
even_numbers_to_left += 1
temporary_left_boundary += 1
nice_subarray_count += even_numbers_to_left + 1
return nice_subarray_count
Case | How to Handle |
---|---|
Empty input array (nums is null or has length 0) | Return 0 immediately, as there are no subarrays to evaluate. |
k is zero and array contains no odd numbers | The entire array constitutes a nice subarray, so we need to count total number of sub-arrays. |
k is larger than the number of odd numbers in the array | Return 0, as it's impossible to form a nice subarray with more odd numbers than available. |
Array contains only even numbers and k > 0 | Return 0 because there are no odd numbers to form a nice subarray with k odd numbers. |
Array contains negative numbers | The solution should work correctly as the 'oddness' of a number is determined by checking if its remainder when divided by 2 is 1 or -1, which we should account for. |
Large input array (nums.length is very large) | A sliding window or prefix sum approach ensures a time complexity of O(n), preventing time limit exceeded errors. |
k is negative | Return 0 immediately, as a negative number of odd numbers is not a valid target. |
Integer overflow possible when calculating the number of subarrays | Use 'long' data type to store number of subarrays, if needed in a particular language. |