class Solution:
def numberOfSubarrays(self, nums, k):
from collections import defaultdict
count = defaultdict(int)
count[0] = 1
res = odd = 0
for num in nums:
odd += num % 2
res += count[odd - k]
count[odd] += 1
return res
class Solution {
public:
int numberOfSubarrays(vector<int>& nums, int k) {
unordered_map<int, int> count;
count[0] = 1;
int odd = 0, res = 0;
for (int num : nums) {
odd += num % 2;
res += count[odd - k];
count[odd]++;
}
return res;
}
};
class Solution {
public int numberOfSubarrays(int[] nums, int k) {
Map<Integer, Integer> count = new HashMap<>();
count.put(0, 1);
int odd = 0, res = 0;
for (int num : nums) {
odd += num % 2;
res += count.getOrDefault(odd - k, 0);
count.put(odd, count.getOrDefault(odd, 0) + 1);
}
return res;
}
}
var numberOfSubarrays = function(nums, k) {
let count = {0: 1};
let odd = 0, res = 0;
for (let num of nums) {
odd += num % 2;
res += count[odd - k] || 0;
count[odd] = (count[odd] || 0) + 1;
}
return res;
};
Given an array of integers nums
and an integer k
, you are asked to count the number of "nice" subarrays. A "nice" subarray is defined as a continuous subarray that contains exactly k
odd numbers.
1 <= nums.length <= 50000
and 1 <= nums[i] <= 10^5
.Your goal is to return the total number of such "nice" subarrays.
The most straightforward way to solve this problem is to consider every possible subarray and count the number of odd numbers in each. However, this brute-force approach is inefficient for large arrays because there are O(n2) possible subarrays.
To optimize, we notice that we are interested in subarrays with exactly k
odd numbers. Instead of checking every subarray, we can keep track of the number of odd numbers seen so far as we iterate through the array. If we know how many times we've seen a certain count of odd numbers before, we can quickly determine how many subarrays ending at the current index have exactly k
odd numbers.
This leads us to consider prefix sums and hash maps to count the occurrences of different "odd count" values efficiently, reducing the number of operations required.
We solve the problem using a prefix sum and hash map approach:
odd - k
odd numbers.
odd - k
odd numbers, it means the subarray between that prefix and the current index contains exactly k
odd numbers. We add the number of such prefixes to our result.
count[0] = 1
to handle the case where the subarray starts from the beginning.
This approach ensures that each element is processed only once, and all lookups and updates in the hash map are O(1).
Let's walk through an example with nums = [1, 1, 2, 1, 1]
and k = 3
.
The final result is 2
, corresponding to the subarrays [1,1,2,1]
and [1,2,1,1]
that each contain exactly 3 odd numbers.
The key insight for this problem is to transform the requirement of finding subarrays with exactly k
odd numbers into a prefix sum problem, where we keep track of the cumulative count of odd numbers. By using a hash map to record the frequency of each odd count, we can instantly determine how many subarrays ending at the current index are "nice." This approach is efficient, elegant, and leverages common prefix sum and hash map strategies to solve what would otherwise be a computationally intensive problem.