給你一個整數數組 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
解題思路
找到滿足要求長度為K的數組,然后左右移動直到碰到下個奇數為止,統計出滿足要求的數組個數。
舉例分析:
案列1:一個數組arr : { 8 6 7 2 2 3 4 6 } ,其中K=2
枚舉出符合要求的子數組:
第一組:
{ 7 2 2 3 }
{ 7 2 2 3 4 }
{ 7 2 2 3 4 6 }
第二組:
{ 6 7 2 2 3 }
{ 6 7 2 2 3 4 }
{ 6 7 2 2 3 4 6 }
第三組:
{ 8 6 7 2 2 3 }
{ 8 6 7 2 2 3 4 }
{ 8 6 7 2 2 3 4 6 }
觀察規律發現,數組的個數由K數組左側的偶數個數m和右側的偶數個數n決定,即(m+1)*(n+1)
需要注意的是為什么+1 ,是因為 { 7 2 2 3 }本身也可以作為起點和終點
接下來我們看案列2,稍微復雜一點,數組中的奇數個數大于K(k=2):
{ 2 3 2 7 2 9 2 }
此時討論滿足需求的數組時就需要考慮在這3個奇數中進行組合的問題了,并且左右擴張時需要注意下個奇數的位置:
第一組:3 和7為界,共4種
{ 3 2 7}
{ 2 3 2 7}
{ 2 3 2 7 2 }
{ 3 2 7 2}
第二組:7 和 9為界,共4種
{ 7 2 9 }
{ 7 2 9 2 }
{ 2 7 2 9 }
{ 2 7 2 9 2 }
所以滿足要求的組和一共是 4 + 4 = 8
通過上面的描述,抽象出數據模式,每種子情況:
(arr[i] - arr[i-1]) * (arr[i+k] - arr[i+k-1]),其中arr是過濾之后的奇數數組。
class Solution {
public int numberOfSubarrays(int[] nums, int k) {
int len = nums.length;
int[] odd = new int[len+2];
int index = 0;
//過濾奇數,放入新數組
for(int i=0;i<len;i++)
{
if((nums[i] & 1) == 1) odd[++index] = i;
}
//擴充兩個邊界,方便后續i-1 和 i+1 越界問題
odd[0] = -1;
odd[index+1] = len;
int res = 0;
for(int i=1;i+k < index+2;i++)
{
res += (odd[i] - odd[i-1]) * (odd[i+k] - odd[i+k-1]);
}
return res;
}
}
題目來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/count-number-of-nice-subarrays
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。