难度中等69收藏分享切换为英文关注反馈
给你一个整数数组 nums
和一个整数 k
。
如果某个 连续 子数组中恰好有 k
个奇数数字,我们就认为这个子数组是「优美子数组」。
请返回这个数组中「优美子数组」的数目。
示例 1:
输入:nums = [1,1,2,1,1], k = 3 输出:2 解释:包含 3 个奇数的子数组是 [1,1,2,1] 和 [1,2,1,1] 。
示例 2:
输入:nums = [2,4,6], k = 1 输出:0 解释:数列中不包含任何奇数,所以不存在优美子数组。
示例 3:
输入:nums = [2,2,2,1,2,2,1,2,2,2], k = 2 输出:16
提示:
1 <= nums.length <= 50000
1 <= nums[i] <= 10^5
1 <= k <= nums.length
这道题有很多变式。直接暴力枚举r=[k,len]然后l=r-k,朝前遍历,最后一个样例过不了的。
然后这题是算奇数,原理是个数问题,且只有偶数和奇数,0不存在的
所以利用前缀和知识,处理一下,又因为是连续数组,所以我们选择前端或者后端,
这里选择后端,又因为后端只与前面存在的有关系,所以就在for中用hashmap来优化一下。
这里用的jdk6所以写的是(map.get(kk[i])==null?0:map.get(kk[i]))+1。
public int numberOfSubarrays(int[] nums, int k) {
int len = nums.length;
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
int[] kk = new int[len+1];
if(nums[0]%2!=0)kk[1]=1;
for(int i = 1 ; i < len ; i++){
kk[i+1]=(nums[i]%2==0?0:1)+kk[i];
}
int res = 0;
map.put(0, 1); // 必须要做的 处理等值情况
for(int i = 1 ; i <= len ; i++){
if(map.containsKey(kk[i]-k)){
res+=map.get(kk[i]-k);
}
map.put(kk[i], (map.get(kk[i])==null?0:map.get(kk[i]))+1);
}
return res;
}