1. Topic introduction
Gives you an integer array nums and an integer k.
If there are exactly k odd numbers in a continuous sub-array, we consider this sub-array to be a "beautiful sub-array".
Please return the number of "beautiful sub-arrays" in this array.
Example 1:
Input: nums = [1,1,2,1,1], k = 3
Output: 2
Explanation: The sub-arrays containing 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: The number sequence does not contain any odd numbers, so there is no graceful sub-array.
Example 3:
Input: nums = [2,2,2,1,2,2,1,2,2,2], k = 2
Output: 16
prompt:
1 <= nums.length <= 50000
1 <= nums[i] <= 10^5
1 <= k <= nums.length
Source: LeetCode
Link: https://leetcode-cn.com/problems/count-number-of-nice-subarrays
Copyright is owned by LeetCode . For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.
Two, problem-solving ideas
- Traverse the array to record the i-th odd number, and store it in vOdd at the subscript position in the array.
- Using the idea of sliding window, keep a "window" with k odd numbers, that is, k odd numbers between vOdd[i] and vOdd[i+k-1].
- Assuming that the left pointer in the above window is l and the right pointer is r, the value range of l is (vOdd[i-1], vOdd[i] ]; the value range of r is [vOdd[i+k-1 ], vOdd[i+k] ). The sub-array between the subscripts corresponding to [l,r] is the graceful sub-array. left = vOdd[i]-vOdd[i-1] represents the number of even numbers from the i-1th odd number to the i-th odd number, the same way right = vOdd[i+k]-vOdd[i+k-1 ] Represents the number of even numbers between the i+k-1 odd number and the i+k odd number. It can be calculated that the number of sub-arrays containing these k odd numbers is left * right.
- Traverse vOdd, calculate the cumulative sum of k odd numbers starting from the i-th odd number, and get the beautiful sub-array.
- Pay attention to the handling of boundary conditions, see the code for details.
Three, problem-solving code
class Solution {
public:
int numberOfSubarrays(vector<int>& nums, int k) {
int n = nums.size();
int cnt = 0;
vector<int> vOdd(n+2, -1);
for(int i = 0; i < n; ++i)
{
if((nums[i] & 1))
vOdd[++cnt] = i; //记录第几个奇数所对应的下标位置
}
vOdd[++cnt] = n;// 为了统计最后一个奇数到数组结尾之间偶数的个数
int res = 0;
for(int i = 1; i + k <= cnt; ++i)
{
res += (vOdd[i] - vOdd[i-1])*(vOdd[i+k] - vOdd[i+k-1]);
}
return res;
}
};