題目
給你一個整數數組 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;
}
}
結尾
使用過二進制進行奇偶數的判斷,但是效果沒有啥提升???按道理應該有提升的。