LeetCode1248-統計「美しいサブアレイ」

1.トピックの紹介

整数配列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

出典:LeetCode
リンク:https ://leetcode-cn.com/problems/count-number-of-nice-subarrays
著作権はLeetCodeが所有しています商用の再版については、公式の承認に連絡してください。非商用の再版については、出典を示してください。

2つの問題解決のアイデア

  • 配列をトラバースしてi番目の奇数を記録し、それをvOddの配列の添え字位置に格納します。
  • スライディングウィンドウのアイデアを使用して、k個の奇数、つまりvOdd [i]とvOdd [i + k-1]の間にk個の奇数を持つ「ウィンドウ」を維持します。
  • 上記のウィンドウの左のポインタがlで、右のポインタがrであるとすると、lの値の範囲は(vOdd [i-1]、vOdd [i]]であり、rの値の範囲は[vOdd [i + k-1]です。 ]、vOdd [i + k])。[l、r]に対応する添え字間のサブアレイは、グレースフルサブアレイです。left = vOdd [i] -vOdd [i-1]は、i-1番目の奇数からi番目の奇数までの偶数の数を表します。right= vOdd [i + k] -vOdd [i + k-1 ] i + k-1奇数とi + k奇数の間の偶数の数を表します。これらのk個の奇数を含むサブアレイの数は左*右であると計算できます。
  • vOddをトラバースし、i番目の奇数から始まるk個の奇数の累積合計を計算して、美しいサブアレイを取得します。
  • ボーダーケースの取り扱いにご注意ください。詳しくはコードをご覧ください。

3つの問題解決コード

class Solution {
public:
    int numberOfSubarrays(vector<int>& nums, int k) {
        int n = nums.size();
        int cnt = 0;
        vector<int> vOdd(n+2, -1);
        for(int i = 0; i < n; ++i)
        {
            if((nums[i] & 1))
                vOdd[++cnt] = i; //记录第几个奇数所对应的下标位置
        }
        vOdd[++cnt] = n;//  为了统计最后一个奇数到数组结尾之间偶数的个数
        int res = 0;
        for(int i = 1; i + k <= cnt; ++i)
        {
            res += (vOdd[i] - vOdd[i-1])*(vOdd[i+k] - vOdd[i+k-1]);
        }
        return res;
    }
};

4つの問題解決の結果

おすすめ

転載: blog.csdn.net/qq_39661206/article/details/105670256