一道題解釋前綴和+二分查找【此後無良辰】

題目描述

在這裏插入圖片描述

基本思路

1.暴力枚舉法 o(n^2);

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

2.雙指針法 時間o(n)

class Solution {
public:
    int left,right;
    int minSubArrayLen(int s, vector<int>& nums) {
        int sum=0,ans=INT_MAX;
        int len=nums.size();
        if(len==0) return 0;
        while(right<len)
        {
            sum+=nums[right];
            while(sum>=s)
            {
                ans=min(ans,right-left+1);
                sum-=nums[left];
                left++;
            }
            right++;
        }
        return ans==INT_MAX?0:ans;
    }
};

前綴和+二分搜索

注意題目保證了所有的數據都是正數
所以可以知道前綴和就一定爲遞增序列
則可以再次使用二分查找把查找的時間複雜度降到o(logn)

class Solution {
public:
   
    int minSubArrayLen(int s, vector<int>& nums) {
        int len=nums.size();
        int ans=INT_MAX;
         vector<int> sum(len+1,0);
         for(int i=1;i<=len;i++)
         {
             sum[i]=sum[i-1]+nums[i-1];//前綴和 sum[i]代表前i個數之合
         }
         for(int i=1;i<=len;i++)
         {
            int target=s+sum[i-1];
            auto bound=lower_bound(sum.begin(),sum.end(),target);//c++自帶的二分查找函數
            if(bound!=sum.end())
            {
                    ans=min(ans,static_cast<int>((bound - sum.begin()) - (i - 1)));
            }
         }
         return ans==INT_MAX?0:ans;
    }
    
};

提交oj

從下到上
暴力法
雙指針
前綴和+二分查找
在這裏插入圖片描述

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