天天看點

1248. 統計「優美子數組」(java)1248. 統計「優美子數組」

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個奇數的左右邊界
    • 找出首個奇數前面數字邊界及第k個奇數的下一個奇數邊界,計算個數
    • (leftEvenCnt + 1) * (rightEvenCnt + 1)
  • 參數說明
    • left 、right為目前k個奇數的最小連續數組範圍
    • leftcnt、rightcnt為除開k個奇數與前後一個奇數的個數(可以進行組合成優美子數組)
class Solution {
    public int numberOfSubarrays(int[] nums, int k) {
        int left=0,right=0,oddCnt=0,res=0;
        while(right<nums.length){
            //或者用nums[right++]&1
            //右指針先走
            if((nums[right++]%2)==1){
                oddCnt++;
            }
            //有k個奇數了
            if(oddCnt==k){
                //開始計算到右邊界個數
                int temp=right;
                while(right<nums.length&&(nums[right]%2)==0) {
                    right++;
                }
                int rightcnt=right-temp;
                //計算到左邊界個數
                int leftcnt=0;
                while((nums[left]%2)==0){
                    left++;
                    leftcnt++;
                }
                //目前可組合的數組數
                res+=(rightcnt+1)*(leftcnt+1);
                //去掉目前數組的首個奇數
                left++;
                oddCnt--;
            }
        }
        return res;
    }
}
           
1248. 統計「優美子數組」(java)1248. 統計「優美子數組」

解法二:字首和

  • 用一個數組prefixCnt存儲
    • 下标是[奇數和],值是[奇數和的個數]
    • sum-k就是要累加的個數,如sum=2 k=2時 在藍色部分情況共4次,每次遇見該情況都計算字首和,即黃色數3+1次,
    • 1248. 統計「優美子數組」(java)1248. 統計「優美子數組」
class Solution {
    public int numberOfSubarrays(int[] nums, int k) {
        int[] prefixCont = new int[nums.length+1];
        prefixCont[0]++;
        int sum=0,res=0;
        for(int num:nums){
            sum+=num%2;
            prefixCont[sum]++;
            if(sum>=k){
                res+=prefixCont[sum-k];
            }
        }
        return res;
    }
}
           
1248. 統計「優美子數組」(java)1248. 統計「優美子數組」