每日一練(45):長度最小的子陣列

加班猿發表於2022-04-25

title: 每日一練(45):長度最小的子陣列

categories:[劍指offer]

tags:[每日一練]

date: 2022/04/19


每日一練(45):長度最小的子陣列

給定一個含有 n 個正整數的陣列和一個正整數 target 。

找出該陣列中滿足其和 ≥ target 的長度最小的 連續子陣列 [numsl, numsl+1, ..., numsr-1, numsr] ,並返回其長度。如果不存在符合條件的子陣列,返回 0 。

示例 1:

輸入:target = 7, nums = [2,3,1,2,4,3]

輸出:2

解釋:子陣列 [4,3] 是該條件下的長度最小的子陣列。

示例 2:

輸入:target = 4, nums = [1,4,4]

輸出:1

示例 3:

輸入:target = 11, nums = [1,1,1,1,1,1,1,1]

輸出:0

提示:

1 <= target <= 109

1 <= nums.length <= 105

1 <= nums[i] <= 105

來源:力扣(LeetCode)

連結:https://leetcode-cn.com/probl...

方法一:佇列模擬滑動視窗

思路分析

使用佇列模擬滑動視窗,並使用一個sum記錄佇列內數的和,由於數的大小有別,所以這裡使用while來推出佇列中的數

int minSubArrayLen(int target, vector<int>& nums) {
    int ans = INT_MAX, sum = 0;
    queue<int> que;
    for (auto &n : nums) {
        sum += n;
        que.push(n);
        while (sum >= target) {
            ans > que.size() ? ans = que.size() : ans;
            sum -= que.front();
            que.pop();
        }
    }
    return ans == INT_MAX ? 0 : ans;
}

方法二:雙指標

思路分析

定義兩個指標i和j指標,將區間[j,i]看成滑動視窗,那麼兩個指標就分別表示滑動視窗的開始位置和結束位置,同時我們再維護一個sum變數用來存貯區間[j,i]連續陣列的和。如果當前滑動視窗維護的區間和sum大於等於target,就說明當前的視窗是可行的,可行中的長度最短的滑動視窗就是答案

int minSubArrayLen(int target, vector<int>& nums) {
    int res = INT_MAX, sum = 0;
    for (int i = 0, j = 0; i < nums.size(); i++) {
        sum += nums[i];//向右擴充套件視窗
        while (sum - nums[j] >= target) {//向左收縮視窗
            sum -= nums[j++];
        } 
        if (sum >= target) {//區間更新
            res = min(res, i - j + 1);
        }
    }
    return res == INT_MAX ? 0 : res;
}

相關文章