leetCode209

今天刷到一道题,有两种解法:滑动窗口和二分法。同时学到了C++中的一个简化二分的函数low_bound()


请看题
给定一个含有 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的大小,若大于target,左边界++,否则右边界++。
代码如下

int minSubArrayLen(int target, vector<int>& nums) {
        int n=nums.size();
        int l=0,r=0,count=0,res=INT_MAX;
        nums.push_back(0);
        while(r<=n){
            if(count<target){
                count+=nums[r];
                r++;
            }else{
                res=res<(r-l)?res:(r-l);
                count-=nums[l];
                l++;
            }
        }
        return res==INT_MAX?0:res;
    }

解法2:二分法

今天才学到。原来在C++里面二分法其实可以用一个函数low_bound就可以轻易实现,low_bound的底层就是二分法实现的
思路如下:左边界从0到n-1。在左边界不变时。通过二分法找到满足条件的右边界。
代码如下

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

今天就总结到这儿啦。以后用到二分法时。一定得记住low_bound这个函数的使用哦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值