leetcode【209】【tag Array】Minimum Size Subarray Sum【c++版本,時間從O(n^2)到O(n)】

問題描述:

Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead.

Example: 

Input: s = 7, nums = [2,3,1,2,4,3]
Output: 2
Explanation: the subarray [4,3] has the minimal length under the problem constraint.

Follow up:

If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n). 

源碼:

先看看O(n^2)的方法。Solution給的解法,用sums[i]存儲i-1下標之前的和。然後每次判斷sums[i]-sums[j]是否大於s且i-j+1是當前最小值,是就換。但是可能用例更行的原因,最後一個用例已經無法通過了。

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int n=nums.size(), result=INT_MAX, sum=0;
        vector<int> sums(n+1, 0);
        for (int i=1; i<=n; i++){
            sums[i] += sums[i-1]+nums[i-1];
            for(int j=i-1; j>=0; j--){
                if(sums[i]-sums[j] >= s){
                    result = min(result, i-j);
                }
            }
        }
        return result!=INT_MAX? result: 0;
    }
};

二分查找法:還是用用sums[i]存儲i-1下標之前的和,用二分查找找大於等於sums[i]+s的下標。時間複雜度O(nlogn)。

學習到了Low_bound函數,詳情可查看lower_bound 與 upper_bound 函數

static_cast是強制轉換

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int n=nums.size(), result=INT_MAX;
        vector<int> sums(n+1, 0);
        for(int i=1; i<=n; i++){
            sums[i] = sums[i-1] + nums[i-1];
        }
        for(int i=1; i<=n; i++){
            int tmp = sums[i-1] + s;
            auto bound = lower_bound(sums.begin()+i-1, sums.end(), tmp);
            if (bound != sums.end()){
                result = min(result, static_cast<int>(bound - (sums.begin()+i-1)));
            }
        }
        return result!=INT_MAX? result: 0;
    }
};

雙指針法,用一個sum保存所有的值的和,用left保存第一個值的位置,每次減去第一個值,看看結果是否大於s。這樣每次再判斷一下result的最小值。該方法應該大概率是屬於O(n)的。

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int n = nums.size(), result=INT_MAX, left=0, sum=0;
        for (int i=0; i<n; i++){
            sum += nums[i];
            while(sum >= s){
                result = min(result, i+1-left);
                sum = sum - nums[left++];
            }
        }
        return result!=INT_MAX? result: 0;
    }
};

 

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