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

于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; 
    }
}
上一篇:Leetcode.697. 数组的度---哈希map存储


下一篇:209.长度最小的子数组