【c++】LeetCode209.长度最小的子数组

给定数组和目标值s,找到和大于等于s的最短连续子数组并返回其长度。示例输入s=7, nums=[2,3,1,2,4,3],输出为2。O(n)解决方案使用滑动窗口,O(n log n)方案结合前缀和和二分查找。" 133404200,19671564,计算编程:深入解析C、Python、Java和JavaScript,"['编程语言', 'C语言', 'Python', 'Java', 'JavaScript']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LeetCode209.长度最小的子数组

https://leetcode-cn.com/problems/minimum-size-subarray-sum
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

示例:
输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

进阶:
如果你已经完成了 O(n) 时间复杂度的解法, 请尝试 O(n log n) 时间复杂度的解法。


O(n)解法 :滑动窗口
定义两个指针 l , r 分别表示窗口的左右两边,其初始位置分别为 0 和 -1 。设置一个变量 sum 表示窗口中数值的和(l~r之间的和)。

先判断sum与 s 的关系:
如果 sum < s ,意味着需要增加窗口长度来提高sum值使其靠近s,此时需要 r++;
如果 sum >= s ,意味着需要减少窗口长度来降低sum值使其靠近s,此时需要 l++;

再判断窗口中的和( sum )是否符合题意,需要进行一次判断 sum >= s。若符合,则将此次窗口的长度与上一次长度比较取出较小的值。

直到遍历完整个数组。
若遍历完整个数组之后仍未发现符合题意的窗口,返回0。

时间复杂度:O(n),其中 n 是数组的长度。指针 l 和 r 最多各移动 n 次。
空间复杂度:O(1)。

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {

        int l = 0, r = -1;
        int minLen = nums.size() + 1;
        int sum = 0;

        while(l < nums.size()) {
            if( r+1 < nums.size() && sum < s ) // 限制r的范围,防止其出去
                sum += nums[++r];
            else 
                sum -= nums[l++];

            if(sum >= s) //此处的sum >= s和上面的else不一样
                minLen = min( minLen, r-l+1 );

        }

        if(minLen == nums.size() + 1) //遍历完了还是原来的值,意味着不符合题意
            return 0;
        return minLen;   
    }
};

O(n log n) 解法:前缀和 + 二分查找
看官方题解吧:说得比我清楚: https://leetcode-cn.com/problems/minimum-size-subarray-sum/solution/chang-du-zui-xiao-de-zi-shu-zu-by-leetcode-solutio/


这是官方提供的题解:https://leetcode-cn.com/problems/minimum-size-subarray-sum/solution/chang-du-zui-xiao-de-zi-shu-zu-by-leetcode-solutio/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值