1. 程式人生 > >【三次過】【滑動視窗】Lintcode 406. 和大於S的最小子陣列

【三次過】【滑動視窗】Lintcode 406. 和大於S的最小子陣列

給定一個由 n 個正整陣列成的陣列和一個正整數 s ,請找出該陣列中滿足其和 ≥ s 的最小長度子陣列。如果無解,則返回 -1。

樣例

給定陣列 [2,3,1,2,4,3] 和 s = 7, 子陣列 [4,3] 是該條件下的最小長度子陣列。

挑戰

如果你已經完成了O(n)時間複雜度的程式設計,請再試試 O(n log n)時間複雜度。

解題思路:

    滑動視窗法。比如現在看到了一個從i到j的一個連續子陣列。


情況1:它的和不到s,那就向後多看一個數據,j++,把這個資料也納入到子陣列中。

情況2:直到看到子陣列的和大於s,那就找到了一個滿足題意的連續子陣列,把它的長度記錄下來。然後從i端縮小子陣列,i--。直到有一時刻子陣列的和小於s,又回到情況1.

class Solution {
public:
    /**
     * @param nums: an array of integers
     * @param s: An integer
     * @return: an integer representing the minimum size of subarray
     */
    int minimumSize(vector<int> &nums, int s) 
    {
        // write your code here
        int l = 0,r = -1;//nums[l...r]為我們的滑動視窗
        int sum = 0;
        int res = nums.size() + 1;//初始化最大值
        
        while(l < nums.size())
        {
            if(r+1 < nums.size() && sum < s) //注意右邊界陣列越界的問題
                sum += nums[++r];
            else
                sum -= nums[l++];
                
            if(sum >= s)
                res = min(res , r-l+1);
        }
        
        if(res == nums.size() + 1) //無解的情況
            return -1;
        else
            return res;
    }
};