滑动窗口之LeetCode209长度最小的子数组

这篇博客探讨了两种方法来解决寻找数组中和大于特定值的最小子数组长度问题。解法1是暴力遍历,通过两层循环找出符合条件的子数组并更新最小长度;解法2采用滑动窗口,通过移动左右指针动态维护窗口内的元素和,当和大于等于目标值时更新最小长度。这两种方法在不同的场景下有不同的效率表现。
摘要由CSDN通过智能技术生成

于2021.11.26练习
题目链接

1.1 解法1:暴力解法之两次遍历

思路:首先初始化这个子组的最小长度为Integer.MAX_VALUE,然后遍历数组的每一个下标作为子组的第一个元素,对于每一个开始下标i,需要找到大于或等于i的最小下标j,使得从nums[i]到nums[j]这个区间内元素之和大于target。如果找到了大于target,就更新最小长度,同时break操作,意味着j下标不用在往下遍历了,因为这个数组全都是正整数,再往后相加只会越来越大。

我自己写的时候,初始化最小长度为nums.length,然后写到最后return语句,不知道该返回什么了,其实只需要用到一个三目运算符,判断此时的最小长度是否为一开始初始化的最小长度,如果等于,那说明并没有找到大于target的子组,就返回0;如果不等于,那说明最小长度后面做了更新,因此返回更新的最小长度即可。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int minLen = Integer.MAX_VALUE;
        for(int i = 0;i < nums.length;i++){
            int sum = 0;
            for(int j = i;j < nums.length;j++){
                sum += nums[j];
                if(sum >= target){
                    minLen = Math.min(minLen,j - i + 1);
                    break;
                }
            }
        }
        return minLen == Integer.MAX_VALUE ? 0 : minLen;
    }
}

1.2 解法2:滑动窗口

思路:用left标记滑动窗口的左指针,用i标记滑动窗口的右指针。i是一直都往后移动的,用于扩张窗口。只有当目前窗口中的元素之和大于等于target时,left指针才会往后移动,用于收缩窗口,同时需要更新子数组的长度,同时窗口中元素之和也需要减去上一个left指向的元素。

注意:只有当前窗口中元素之和 大于等于target,就要让left一直移动,因此这个过程需要用while循环实现,而不应该用if实现。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int left = 0;
        int minLen = Integer.MAX_VALUE;
        int sum = 0;
        for(int i = 0;i < nums.length;i++){
            sum += nums[i];
            while(sum >= target){
                minLen = Math.min(minLen,i - left + 1);
                sum -= nums[left];
                left++;
            }
        }
        return minLen == Integer.MAX_VALUE ? 0 : minLen; 
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值