给你一个整数数组 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 = [2,2,2,1,2,2,1,2,2,2,1,2], k = 2
规律:比如是k是2,先分割出一个数组从偶数开始到下一个k+1个奇数之前的数字组成一个数组,
比如题目所找出的数组为:nums = [2,2,2,1,2,2,1,2,2,2],其中数组长度为10,其中记录起始偶数位置为
start = 0,第一个奇数位置为firstKey = 3,最后一个奇数位置为endKey = 6,末尾偶数位置为end = 9,
则优美子数组个数 = (firstKey - start) + (end - endKey) + (firstKey - start)*(end - endKey) + 1;
2、遍历数组,如果数字为偶数,则直接进入下一层循环
3、如果为奇数:则记录出现奇数的次数,当刚好组成如上一个数组时候则开始计算个数。
4、对于最后一种,一整个数组刚好为以上规律数组时候则计算。
5、返回数目
import java.util.LinkedList;
class Solution {
public int numberOfSubarrays(int[] nums, int k) {
LinkedList<Integer> flagList = new LinkedList();
int result = 0;
int times = 0;
flagList.add(0);
for (int i = 0; i < nums.length; i ++) {
if (nums[i]%2 == 0) {
continue;
}
times++;
if (times > k) {
flagList.add(i - 1);
int start = flagList.getFirst();
int firstKey = flagList.get(1);
int end = flagList.getLast();
int endKey = flagList.get(flagList.size()- 2);
int beforeKey = firstKey - start;
int afterKey = end - endKey;
result += beforeKey + afterKey + beforeKey*afterKey + 1;
flagList.removeFirst();
flagList.set(0,firstKey + 1);
flagList.removeLast();
times--;
}
flagList.add(i);
}
if (times == k) {
flagList.add(nums.length - 1);
int start = flagList.getFirst();
int firstKey = flagList.get(1);
int end = flagList.getLast();
int endKey = flagList.get(flagList.size() - 2);
int beforeKey = firstKey - start;
int afterKey = end - endKey;
result += beforeKey + afterKey + beforeKey*afterKey + 1;
}
return result;
}
}
使用过二进制进行奇偶数的判断,但是效果没有啥提升???按道理应该有提升的。