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

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/count-number-of-nice-subarrays
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

二、解題思路

  • 遍歷數組記錄第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個奇數的子數組個數爲left * right。
  • 遍歷vOdd,計算以第i個奇數爲起點的k個奇數,所能得到的優美子數組的累加和。
  • 注意邊界情況的處理,詳細請見代碼。

三、解題代碼

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;
    }
};

四、解題結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章