LeetCode 1248: Count Number of Nice Subarrays (Sliding Window)
Source: https://leetcode.com/problems/count-number-of-nice-subarrays/
English
Count subarrays with exactly k odd numbers by subtraction: exactly(k) = atMost(k) - atMost(k-1). The sliding window for atMost(k) adds all valid windows ending at each right pointer.
Code
class Solution {
public int numberOfSubarrays(int[] nums, int k) {
return atMost(nums, k) - atMost(nums, k - 1);
}
private int atMost(int[] nums, int k) {
int l = 0, ans = 0;
for (int r = 0; r < nums.length; r++) {
if ((nums[r] & 1) == 1) k--;
while (k < 0) {
if ((nums[l] & 1) == 1) k++;
l++;
}
ans += r - l + 1;
}
return ans;
}
}func numberOfSubarrays(nums []int, k int) int {
return atMost(nums, k) - atMost(nums, k-1)
}
func atMost(nums []int, k int) int {
l, ans := 0, 0
for r := 0; r < len(nums); r++ {
if nums[r]%2 == 1 {
k--
}
for k < 0 {
if nums[l]%2 == 1 {
k++
}
l++
}
ans += r - l + 1
}
return ans
}class Solution {
public:
int numberOfSubarrays(vector<int>& nums, int k) {
return atMost(nums, k) - atMost(nums, k - 1);
}
int atMost(vector<int>& nums, int k) {
int l = 0, ans = 0;
for (int r = 0; r < (int)nums.size(); r++) {
if (nums[r] % 2 == 1) k--;
while (k < 0) {
if (nums[l] % 2 == 1) k++;
l++;
}
ans += r - l + 1;
}
return ans;
}
};class Solution:
def numberOfSubarrays(self, nums: List[int], k: int) -> int:
def at_most(k: int) -> int:
l = 0
ans = 0
for r, v in enumerate(nums):
if v % 2 == 1:
k -= 1
while k < 0:
if nums[l] % 2 == 1:
k += 1
l += 1
ans += r - l + 1
return ans
return at_most(k) - at_most(k - 1)var numberOfSubarrays = function(nums, k) {
const atMost = (k) => {
let l = 0, ans = 0;
for (let r = 0; r < nums.length; r++) {
if (nums[r] % 2 === 1) k--;
while (k < 0) {
if (nums[l] % 2 === 1) k++;
l++;
}
ans += r - l + 1;
}
return ans;
};
return atMost(k) - atMost(k - 1);
};中文
恰好包含 k 个奇数的子数组数量,可以转化为:exactly(k) = atMost(k) - atMost(k-1)。其中 atMost(k) 用滑动窗口统计“最多 k 个奇数”的子数组个数,每次右指针推进后,累加当前有效窗口数。
代码
class Solution {
public int numberOfSubarrays(int[] nums, int k) {
return atMost(nums, k) - atMost(nums, k - 1);
}
private int atMost(int[] nums, int k) {
int l = 0, ans = 0;
for (int r = 0; r < nums.length; r++) {
if ((nums[r] & 1) == 1) k--;
while (k < 0) {
if ((nums[l] & 1) == 1) k++;
l++;
}
ans += r - l + 1;
}
return ans;
}
}func numberOfSubarrays(nums []int, k int) int {
return atMost(nums, k) - atMost(nums, k-1)
}
func atMost(nums []int, k int) int {
l, ans := 0, 0
for r := 0; r < len(nums); r++ {
if nums[r]%2 == 1 {
k--
}
for k < 0 {
if nums[l]%2 == 1 {
k++
}
l++
}
ans += r - l + 1
}
return ans
}class Solution {
public:
int numberOfSubarrays(vector<int>& nums, int k) {
return atMost(nums, k) - atMost(nums, k - 1);
}
int atMost(vector<int>& nums, int k) {
int l = 0, ans = 0;
for (int r = 0; r < (int)nums.size(); r++) {
if (nums[r] % 2 == 1) k--;
while (k < 0) {
if (nums[l] % 2 == 1) k++;
l++;
}
ans += r - l + 1;
}
return ans;
}
};class Solution:
def numberOfSubarrays(self, nums: List[int], k: int) -> int:
def at_most(k: int) -> int:
l = 0
ans = 0
for r, v in enumerate(nums):
if v % 2 == 1:
k -= 1
while k < 0:
if nums[l] % 2 == 1:
k += 1
l += 1
ans += r - l + 1
return ans
return at_most(k) - at_most(k - 1)var numberOfSubarrays = function(nums, k) {
const atMost = (k) => {
let l = 0, ans = 0;
for (let r = 0; r < nums.length; r++) {
if (nums[r] % 2 === 1) k--;
while (k < 0) {
if (nums[l] % 2 === 1) k++;
l++;
}
ans += r - l + 1;
}
return ans;
};
return atMost(k) - atMost(k - 1);
};
Comments