209、长度最小的子数组(数组)

本文介绍了一种寻找数组中和≥s的最短连续子数组的方法,包括暴力解法和高效的滑动窗口算法,后者通过动态调整窗口大小来降低时间复杂度。

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

 题目:

给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

示例:

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

方法一:暴力解法

public int minSubArrayLen(int s,int[] nums){
    int n = nums.length;
    //子序列之和
    int sum =0;
    //子序列长度
    int subLength =0;
    int res = Integer.MAX_VALUE;
        for (int i = 0; i <n ; i++) {
            //设置子序列起点
            sum=0;
            for (int j = i; j <n ; j++) {
                //设置子序列终点
                sum+=nums[j];
                if(sum >=s){
                    //更新子序列长度
                    subLength = j-i+1;
                    res = Math.min(res, subLength);
                    break;//如果找到了最小子数组,跳出设置子序列终点的第二层循环,增加子序列起点继续遍历
                }
            }
        }
        //如果res没有被赋值的话,就返回0,说明没有符合条件的子序列
        return res == Integer.MAX_VALUE ? 0:res;
    }

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

空间复杂度:O(1)

方法二:滑动窗口(双指针)

思路:使用左右指针动态地维护和大于s的最小的子数组

//方法二:滑动窗口(双指针)
    public int minSubArrayLen(int s,int[] nums){
        //数组长度
        int n = nums.length;
        //子序列之和
        int sum = 0;
        //子序列长度
        int subLength = 0;
        //子序列结果
        int result = Integer.MAX_VALUE;
        //滑动窗口起始位置
        int left =0;
        for (int right=0;right<n;right++) {
            sum+= nums[right];
            while (sum>=s){
                subLength = right-left+1;
                result = Math.min(result, subLength);
                sum-=nums[left++];
            }
        }
        return result==Integer.MAX_VALUE? 0: result;
    }

时间复杂度:O(n)

空间复杂度:O(1)

为什么for循环里面嵌套while循环时间复杂度是O(n)?

因为时间复杂度考查的是每一个元素重复出现的次数,在滑动窗口中,元素在进入窗口时出现一次,离开窗口时出现一次。因此每一个元素被操作两次,时间复杂度应该是O(2n),也就是O(n)了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值