Count Number of Nice Subarrays
Given an array of integers nums and an integer k, a subarray is called nice if it contains exactly k odd numbers . Return the number of nice subarrays. Count subarrays with at most k odd numbers, subtract the count with at most k minus one, and the difference is exactly k.
Constraints
- 1 ≤ nums.length ≤ 5 × 104
- 1 ≤ numsi ≤ 105
- 0 ≤ k ≤ nums.length
Example
nums = [1, 1, 2, 1, 1], k = 32Explanation The two nice subarrays are [1,1,2,1] and [1,2,1,1], each containing exactly 3 odd numbers.
Count-at-most(k) minus count-at-most(k-1)
Window [1,1,2,1] has 3 odd numbers <= 3; add 4 to the running count.
What happens in this step
atMost(3) — right=3, window [1,1,2,1] (left=0) odd values in window: 1, 1, 1 → oddCount = 3 3 <= 3 → within limit, no shrinking count += (right - left + 1) = (3 - 0 + 1) = 4
Steps to visualize
- Run a variable window that counts subarrays with at most a target number of odd values.
- Grow right and increment the odd counter when the new value is odd.
- While the odd counter exceeds the target, shrink from the left.
- At each right position, add the current window size to the count.
- Call this helper for k and for k minus one, then subtract.
Walk through the code
Same walkthrough, now with the code. Press Next to move one step and watch which lines run.
Window [1,1,2,1] has 3 odd numbers <= 3; add 4 to the running count.
What happens in this step
atMost(3) — right=3, window [1,1,2,1] (left=0) odd values in window: 1, 1, 1 → oddCount = 3 3 <= 3 → within limit, no shrinking count += (right - left + 1) = (3 - 0 + 1) = 4
Solution
function numberOfSubarrays(nums, k) {
function atMost(limit) {
if (limit < 0) return 0;
let left = 0;
let oddCount = 0;
let count = 0;
for (let right = 0; right < nums.length; right++) {
if (nums[right] % 2 !== 0) oddCount++;
while (oddCount > limit) {
if (nums[left] % 2 !== 0) oddCount--;
left++;
}
count += right - left + 1;
}
return count;
}
return atMost(k) - atMost(k - 1);
}- Time
- O(n)
- Space
- O(1)
Test cases
| Input | Expected | Covers |
|---|---|---|
nums = [1, 1, 2, 1, 1], k = 3 | 2 | Docstring example |
nums = [2, 4, 6], k = 0 | 6 | k = 0 counts every run of pure evens |
nums = [1, 3, 5], k = 2 | 2 | All odd numbers |
nums = [2, 4, 6], k = 1 | 0 | k larger than the total odd count |
nums = [1], k = 1 | 1 | Single odd element |
nums = [1, 1, 1], k = 1 | 3 | Every single-element window qualifies |
nums = [2, 1, 2, 1, 2], k = 2 | 4 | Mixed evens and odds with multiple valid windows |