使用到前缀和技巧,不过这里的前缀和统计的不是和,而是奇数的个数
如示例1:
nums = [1, 1, 2, 1, 1]
preOdd = [0, 1, 2, 2, 3, 4]
preOdd[j] - preOdd[i]
这个式子可以得到nums在[i, j)区间中奇数的个数
然后就可以循环这个preOdd数组,双指针寻找差值为k的次数。
class Solution {
private:
vector<int> preOdd;
public:
int numberOfSubarrays(vector<int>& nums, int k) {
int size = nums.size();
preOdd.resize(size + 1, 0);
for (int i = 1; i < size + 1; i++)
{
if (nums[i - 1] & 1)
preOdd[i] = preOdd[i - 1] + 1;
else
preOdd[i] = preOdd[i - 1];
}
int ans = 0;
for (int i = 1; i < size + 1; i++)
{
for (int j = 0; j < i; j++)
{
if (preOdd[i] - preOdd[j] == k)
ans++;
}
}
return ans;
}
};
上面的写法会超时,很眼熟啊,和【中等】和为K的子数组一题一样使用哈希进行优化
class Solution {
private:
vector<int> preOdd;
public:
int numberOfSubarrays(vector<int>& nums, int k) {
int size = nums.size();
preOdd.resize(size + 1, 0);
for (int i = 1; i < size + 1; i++)
{
if (nums[i - 1] & 1)
preOdd[i] = preOdd[i - 1] + 1;
else
preOdd[i] = preOdd[i - 1];
}
int ans = 0;
map<int, int> mp;
for (int i = 0; i < size + 1; i++)
{
if (mp[preOdd[i] - k] > 0)
ans += mp[preOdd[i] - k];
mp[preOdd[i]]++;
}
return ans;
}
};