##### Welcome to Subscribe On Youtube

Formatted question description: https://leetcode.ca/all/1248.html

# 1248. Count Number of Nice Subarrays (Medium)

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 is 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

Related Topics: Two Pointers

## Solution 1. Map

Use a map m to store the mapping from the count of odd numbers cnt to the first index in the array that has cnt numbers in front of it and including itself.

When cnt >= k, we add m[cnt - k + 1] - m[cnt - k] to the answer.

// OJ: https://leetcode.com/problems/count-number-of-nice-subarrays/
// Time: O(N)
// Space: O(N)
class Solution {
public:
int numberOfSubarrays(vector<int>& A, int k) {
int N = A.size(), cnt = 0, ans = 0;
unordered_map<int, int> m{ {0,-1} };
for (int i = 0; i < N; ++i) {
cnt += A[i] % 2;
if (m.count(cnt) == 0) m[cnt] = i;
if (cnt >= k) ans += m[cnt - k + 1] - m[cnt - k];
}
return ans;
}
};


## Solution 2. Two Pointers

Assume the current pointer is j and the corresponding odd number count is cj, we need two pointers to get the answer.

The first pointer i is the index whose corresponding odd number count is cj - k + 1.

The second pointer prev is the index whose corresponding odd number count is cj - k.

So when cj >= k, we add i - prev to the answer.

// OJ: https://leetcode.com/problems/count-number-of-nice-subarrays/
// Time: O(N)
// Space: O(1)
class Solution {
public:
int numberOfSubarrays(vector<int>& A, int k) {
int N = A.size(), i = 0, j = 0, prev = -1, ans = 0, ci = 0, cj = 0;
while (j < N) {
cj += A[j++] % 2;
if (ci <= cj - k) {
prev = i;
while (ci <= cj - k) ci += A[i++] % 2;
}
if (cj >= k) ans += i - prev;
}
return ans;
}
};


Or use a single count.

// OJ: https://leetcode.com/problems/count-number-of-nice-subarrays/
// Time: O(N)
// Space: O(1)
class Solution {
public:
int numberOfSubarrays(vector<int>& A, int k) {
int N = A.size(), i = 0, j = 0, prev = -1, ans = 0, cnt = 0;
while (j < N) {
int c = A[j++] % 2;
cnt += c;
if (c && cnt >= k) {
prev = i;
while (A[i] % 2 == 0) ++i;
++i;
}
if (cnt >= k) ans += i - prev;
}
return ans;
}
};


## Solution 3. At Most

Exactly k times = At Most k times - At Most k - 1 times.

// OJ: https://leetcode.com/problems/count-number-of-nice-subarrays/
// Time: O(N)
// Space: O(1)
// Ref: https://leetcode.com/problems/count-number-of-nice-subarrays/discuss/419378/JavaC%2B%2BPython-Sliding-Window-O(1)-Space
class Solution {
int atMost(vector<int> &A, int k) {
int N = A.size(), i = 0, ans = 0;
for (int j = 0; j < N; ++j) {
k -= A[j] % 2;
while (k < 0) k += A[i++] % 2;
ans += j - i;
}
return ans;
}
public:
int numberOfSubarrays(vector<int>& A, int k) {
return atMost(A, k) - atMost(A, k - 1);
}
};

• class Solution {
public int numberOfSubarrays(int[] nums, int k) {
List<Integer> oddIndices = new ArrayList<Integer>();
int length = nums.length;
for (int i = 0; i < length; i++) {
if (nums[i] % 2 != 0)
}
int count = 0;
int oddIndicesSize = oddIndices.size() - 2;
int start = 1, end = oddIndicesSize - k + 1;
for (int low = start; low <= end; low++) {
int high = low + k - 1;
int indexLow = oddIndices.get(low), indexHigh = oddIndices.get(high);
int indexPrev = oddIndices.get(low - 1), indexNext = oddIndices.get(high + 1);
count += (indexLow - indexPrev) * (indexNext - indexHigh);
}
return count;
}
}

############

class Solution {
public int numberOfSubarrays(int[] nums, int k) {
int n = nums.length;
int[] cnt = new int[n + 1];
cnt[0] = 1;
int ans = 0, t = 0;
for (int v : nums) {
t += v & 1;
if (t - k >= 0) {
ans += cnt[t - k];
}
cnt[t]++;
}
return ans;
}
}

• // OJ: https://leetcode.com/problems/count-number-of-nice-subarrays/
// Time: O(N)
// Space: O(N)
class Solution {
public:
int numberOfSubarrays(vector<int>& A, int k) {
int N = A.size(), cnt = 0, ans = 0;
unordered_map<int, int> m{ {0,-1} };
for (int i = 0; i < N; ++i) {
cnt += A[i] % 2;
if (m.count(cnt) == 0) m[cnt] = i;
if (cnt >= k) ans += m[cnt - k + 1] - m[cnt - k];
}
return ans;
}
};

• class Solution:
def numberOfSubarrays(self, nums: List[int], k: int) -> int:
cnt = Counter({0: 1})
ans = t = 0
for v in nums:
t += v & 1
ans += cnt[t - k]
cnt[t] += 1
return ans

############

# 1248. Count Number of Nice Subarrays
# https://leetcode.com/problems/count-number-of-nice-subarrays/

class Solution:
def numberOfSubarrays(self, nums: List[int], k: int):
res = i = count = 0

for j,x in enumerate(nums):
if x & 1:
k -= 1
count = 0

while k == 0:
k += nums[i] & 1
i += 1
count += 1

res += count

return res

def numberOfSubarrays(self, nums: List[int], k: int):
n = len(nums)
prefix = [0]
start = float('inf')
mp = collections.defaultdict(int)
mp[0] = 1

for num in nums:
prefix.append(prefix[-1] + int(num % 2 == 1))
if prefix[-1] >= k:
start = min(start, len(prefix)-1)
mp[prefix[-1]] += 1

if start == float('inf'): return 0

res = 0
for i in range(start, len(prefix)):
if prefix[i] - k in mp:
res += mp[prefix[i]-k]

return res

• func numberOfSubarrays(nums []int, k int) (ans int) {
n := len(nums)
cnt := make([]int, n+1)
cnt[0] = 1
t := 0
for _, v := range nums {
t += v & 1
if t >= k {
ans += cnt[t-k]
}
cnt[t]++
}
return
}

• function numberOfSubarrays(nums: number[], k: number): number {
const n = nums.length;
const cnt = new Array(n + 1).fill(0);
cnt[0] = 1;
let ans = 0;
let t = 0;
for (const v of nums) {
t += v & 1;
if (t - k >= 0) {
ans += cnt[t - k];
}
cnt[t] += 1;
}
return ans;
}