LC.209. 长度最小的子数组

LC.209. 长度最小的子数组

方法0:O(n2)O(n^2)的纯暴力,这里不讲。

方法1:前缀和+二分。

考虑将其转化为具有单调性的前缀和数组,然后枚举区间左端点进行二分找答案即可。

时间复杂度:O(nlogn)O(nlogn)

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& a) {
         vector<int>pre(a.size()+1);
         for(int i=1;i<=a.size();i++)
                pre[i]=pre[i-1]+a[i-1];
        int ans=1e9;
        for(int i=1;i<=a.size();i++){
            int p=lower_bound(pre.begin()+i,pre.end(),s+pre[i-1])-pre.begin();
            //printf("i=%d,p=%d\n",i,p);
            if(p!=a.size()+1) ans=min(ans,p-i+1);
        }
        return ans==1e9?0:ans;
    }
};

方法2:尺取法&双指针法。

因为区间和具有单调性,考虑枚举区间右端点,然后不断移动左指针至sum<ssum<s,再进行右指针++++.

时间复杂度:O(n)O(n)

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& a) {
         int st=0,ed=0;
         int ans=1e9,sum=0;
         while(ed<a.size()){
             sum+=a[ed];
             while(sum>=s){
                 ans=min(ans,ed-st+1);
                 if(ans==1) return 1;
                 sum-=a[st];
                 st++;
             }
             ed++;
         }
         return ans==1e9?0:ans;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章