You are given an array of integers nums
and an integer k
. A continuous subarray is considered nice if it contains exactly k
odd numbers.
Your task is to return the number of nice subarrays present in the given array.
Example 1:
Input: nums = [1,1,2,1,1], k = 3
Output: 2
Explanation: The subarrays 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
Solve this problem efficiently, considering the constraints:
1 <= nums.length <= 50000
1 <= nums[i] <= 10^5
1 <= k <= nums.length
The most straightforward approach is to consider all possible subarrays and count the number of odd numbers in each subarray. If a subarray contains exactly k
odd numbers, we increment the count.
k
, increment the result.def numberOfSubarrays_brute_force(nums, k):
count = 0
for i in range(len(nums)):
for j in range(i, len(nums)):
odd_count = 0
for l in range(i, j + 1):
if nums[l] % 2 != 0:
odd_count += 1
if odd_count == k:
count += 1
return count
A more efficient approach involves using a sliding window. The idea is to maintain a window and adjust its size such that it always contains k
odd numbers. We can further optimize by counting the number of even numbers before the first odd number and after the last odd number in the window.
atMost(nums, k)
which finds the number of subarrays with at most k
odd numbers.atMost(nums, k) - atMost(nums, k - 1)
.atMost(nums, k)
left = 0
, count = 0
, and odd_count = 0
.right
pointer.nums[right]
is odd, increment odd_count
.odd_count > k
, move the left pointer and decrement odd_count
if nums[left]
is odd.right - left + 1
to the count
.count
.def numberOfSubarrays(nums, k):
def atMost(nums, k):
left = 0
count = 0
odd_count = 0
for right in range(len(nums)):
if nums[right] % 2 != 0:
odd_count += 1
while odd_count > k:
if nums[left] % 2 != 0:
odd_count -= 1
left += 1
count += right - left + 1
return count
return atMost(nums, k) - atMost(nums, k - 1)
k
is 0, the atMost
function will count subarrays with no odd numbers.atMost(nums, k-1)
will return a non-zero value and ensures the correct result even when k exceeds the number of odd numbers in the arrayk > 0
, the function returns 0, which is correct.