【Leetcode】209. 长度最小的子数组

题目描述

在这里插入图片描述

// 209. 长度最小的子数组


// 给定一个含有 n 个正整数的数组和一个正整数 target 。

// 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., 
// numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

题解

// 队列滑窗法
// 要解题,先怎么简单怎么来。

// 定义一个队列q(LinkedList来模拟),定义sum变量来记录队列窗口q中元素的
// 和。我们用队列q来模拟我们要的连续子数组,遍历到的元素存入q中,并记录q
// 元素的和sum,如果sum大于等于target,则贪心地将q.size()和答案保存位res
// (初始化为Integer.MAX_VALUE)中最小的那个更新给res。然后将q的队列头(
// 最早入队的)元素删除。删除队列头元素之后sum值还有可能大于等于target,
// 删完之后还不能走,所以用一个while子循环嵌套一下,如果删除队列头元素
// 之后sum值还大于等于target,且q不为空,那继续将贪心地将q.size()和答案保
// 存位res中最小的那个更新给res。
// 
// 执行用时:6 ms, 在所有 Java 提交中击败了20.22%的用户
// 内存消耗:39.4 MB, 在所有 Java 提交中击败了5.00%的用户
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        LinkedList<Integer> q = new LinkedList<>();
        int res = Integer.MAX_VALUE;
        int sum = 0;
        for (int i = 0; i < nums.length; i++) {
            q.add(nums[i]);
            sum += nums[i];
            
            while (!q.isEmpty() && sum >= target) {
                res = Math.min(res, q.size());
                sum -= q.removeFirst();
            }
        }
        return (res == Integer.MAX_VALUE) ? 0 : res;
    }
}

// 双指针滑窗法
// 其实想到双指针法但是不知道怎么实现的,等写出来队列滑窗法之后,自然就知道
// 了。改一改就是双指针法,left指针是队列窗口的左边界,right指针是队列窗口
// 的右边界,这里的right跟队列划窗法for循环中的i是一样的,只是这里不需要
// 把元素存入q中了,直接将遍历到的nums[right]累加给sum,而while子循环中
// 的q不为空要改为left <= right,这里允许left和right相遇的情况,相遇时相当
// 与窗口中只有一个元素。q.size()改为right-left+1,窗口左元素(队列头元素)
// 删除掉之后,left手动右移。
// 
// 执行用时:2 ms, 在所有 Java 提交中击败了83.69%的用户
// 内存消耗:38 MB, 在所有 Java 提交中击败了98.32%的用户
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int res = Integer.MAX_VALUE;
        int sum = 0;
        int left = 0;
        for (int right = 0; right < nums.length; right++) {
            sum += nums[right];
            
            while (left <= right && sum >= target) {
                res = Math.min(res, right - left + 1);
                sum -= nums[left++];
            }
        }
        return (res == Integer.MAX_VALUE) ? 0 : res;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

锥栗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值