leetcode 209. 长度最小的子数组

本文介绍了两种优化的滑动窗口方法,解决如何找到给定数组中满足和大于等于目标值s的最小子数组长度。方法一是常规的迭代实现,方法二是时间复杂度较低的版本,通过两次嵌套循环巧妙地避免了重复计算。关键在于理解窗口的移动和sum的更新策略。

在这里插入图片描述
原题链接

  1. 使用滑动窗口的方法
  2. 首先定义left和 sum
  3. 从right为0 时,开始遍历,不断累加sum
  4. 当sum满足 大于等于s 的时候,判断 ans的最小长度
  5. 然后让sum 减去当前的 nums[left],然后将left++,再次进入while循环。这一步的含义是:不断变更序列的开始位置,即寻找满足sum >= s 时的 right - left + 1 的最小值能为多少
  6. 最后返回ans
  7. 二刷:注意for循环时,定义right= 0,而不是i = 0
  8. 注意:在选择ans的时候,是要求 Math.min(…) 而不是max
  9. 注意 for 循环内开始的时候 right = 0
方法一 

class Solution {
    // 滑动窗口
    public int minSubArrayLen(int s, int[] nums) {
        int left = 0;
        int sum = 0;
        int ans = Integer.MAX_VALUE;
        for(int right = 0; right < nums.length; right++){
            sum += nums[right];
            while(sum >= s){
                ans = Math.min(ans, right - left + 1);
                //将sum 减去当前的nums[left]
                sum -= nums[left];
                // 这里体现出滑动窗口的精髓之处,不断变更(子序列的起始位置)
                left++;
            }
        }
        return ans == Integer.MAX_VALUE ? 0 : ans; 
    }
}



方法二 (时间复杂度高)另一种滑动窗口方法

 class Solution {
    public int minSubArrayLen(int s, int[] nums) {
//将此题当作不考虑连续子数组的情况
        int n = nums.length;
        if(n == 0) return 0;
        int ans = Integer.MAX_VALUE;
        for(int i = 0; i < n; i++){
            int sum = 0;
            for(int j = i; j < n; j++){
                sum += nums[j];
                if(sum >= s){
                    ans = Math.min(ans, j - i + 1);
                    break;
                }
            }
        }
        return ans == Integer.MAX_VALUE ? 0 : ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值