Leetcode每日一題1248-統計「優美子數組」

給你一個整數數組 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
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容