Java力扣---滑动窗口(1)

239. 滑动窗口最大值 - 力扣(LeetCode)

分析:

1.滑动窗口是有元素先进先出的特性的所以可以考虑到队列

2.因为前面的元素是要被删除的,如果考虑常规做法,需要不断地重复计算已经计算过的值


知识点:单调队列=双端队列+单调性


为什么要保证单调?

我们现在要求得是窗口内的最大值,也就是说,如果进来了比当前最大值还要大的,那么当前值在后续将不再成为最大值,所以可以把它清除出去,但是如果进来的是比现在的小的,虽然当前不是最大值,但是当窗口划过当前值之后,他就有可能成为最大值了,所以要保留,这就是为什么求滑动窗口最大值的时候要保证递减;同理,求滑动窗口最小值的时候,要保留比当前值大的数,而不用保留比当前值小的数,所以要保证递增


单调性如何确定?(以严格递减为例)

在队列非空,并且排队的元素比现在队列的最后一个元素大的时候

如果这个排队的元素进来,会导致严格递减不成立

所以把最后一个元素删除

但是这并不意味着倒数第二个,第三个元素就比排队的要大,所以在这一步要用到循环

这样才可以保证新元素进来的时候依然是是递减的,这个时候才让新元素进来


为什么要在队列中放序号而不是数值?

因为是窗口,要保证先进先出,如果直接放数值,那么就没有窗口的顺序了-----要保证数据是在窗口内的


新元素进来可能会导致窗口溢出,所以要判断需不需要把最前面的元素删除

在本题中,还要顾及到记录该窗口的最大值

java 复制代码
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;

public class test {
    static void main() {
        int[] nums = {1, 3, -1, -3, 5, 3, 6, 7};
        int k = 1;
        System.out.println(Arrays.toString(maxSlidingWindow(nums, k)));
    }

    public static int[] maxSlidingWindow(int[] nums, int k) {

        Deque<Integer> queue = new ArrayDeque<>();
        int[] arr = new int[nums.length - k + 1];
        //遍历
        for (int i = 0; i < nums.length; i++) {
            //先加新数
            //判queue空不空
            while (!queue.isEmpty() && nums[queue.getLast()] < nums[i]) {
                //如果新来的数更大
                //那么前面的都不再是我后面会用到的最大值
                //把比新来的小的都清除
                queue.removeLast();
            }
            //没满的则要判断是否进队
            //如果新来的数更小
            //那就让他进来,因为可能是后面的数里面的最大值
            queue.addLast(i);

            //判断该不该清除前面的(size够不够)
            int left = i - k + 1;
            if (left > queue.getFirst()) {
                //要把左边的移出去
                queue.removeFirst();
            }
            //记录滑动窗口的最大值
            if (left >= 0) arr[left] = nums[queue.getFirst()];
        }
        return arr;
    }
}

1438. 绝对差不超过限制的最长连续子数组

选择滑动窗口的原因:子数组越长,最大值越大,最小值越小,越不能满足本题的要求,反之,子数组越短,越能满足本题的要求--------满足这样的性质的,可以用滑动窗口


由于要计算的是最大值和最小值之间的差异,所以要记录最大值和最小值两个数值,要定义两个队列,一个用来存放最大值,一个放最小值

但是最大值越大,最小值越小,越容易不满足题目要求-------所以最大值要缩小,最小值要变大--------所以最大值队列要递减,最小值队列要递增

如果最大值和最小值之间的差距过大了,那么就要踢出去他们其中的一个----谁先进来的谁先出去----所以要有一个数值记录窗口的开始在哪里,如果当前超出限制,那么窗口就要滑动,也就是开始值要加一

java 复制代码
import java.util.ArrayDeque;
import java.util.Deque;

public class test {
    static void main() {
        int[] nums = {10, 1, 2, 4, 7, 2};
        int k = 5;
        System.out.println(maxSlidingWindow(nums, k));
    }

    public static int maxSlidingWindow(int[] nums, int limit) {
        Deque<Integer> maxqueue = new ArrayDeque<>();
        Deque<Integer> minqueue = new ArrayDeque<>();

        int left = 0;
        int maxnum = 0;

        for (int i = 0; i < nums.length; i++) {
            //让最大队列递减,让最小队列递增
            while (!maxqueue.isEmpty() && nums[maxqueue.getLast()] < nums[i]) {
                maxqueue.removeLast();
            }
            maxqueue.addLast(i);
            while (!minqueue.isEmpty() && nums[minqueue.getLast()] > nums[i]) {
                minqueue.removeLast();
            }
            minqueue.addLast(i);
            //做判断,如果在大于限制,要右滑窗口,把最前面的窗口移出去
            while (nums[maxqueue.getFirst()] - nums[minqueue.getFirst()] > limit) {
                left++;
                if (maxqueue.getFirst() < left) {
                    maxqueue.removeFirst();
                }
                if (minqueue.getFirst() < left) {
                    minqueue.removeFirst();
                }
            }
            maxnum = Math.max(maxnum, i - left + 1);
        }
        return maxnum;
    }
}

学习思路来自灵茶山艾府 - 力扣(LeetCode)

相关推荐
忧郁的Mr.Li5 小时前
SpringBoot中实现多数据源配置
java·spring boot·后端
啊森要自信5 小时前
CANN ops-cv:AI 硬件端视觉算法推理训练的算子性能调优与实战应用详解
人工智能·算法·cann
yq1982043011566 小时前
静思书屋:基于Java Web技术栈构建高性能图书信息平台实践
java·开发语言·前端
一个public的class6 小时前
你在浏览器输入一个网址,到底发生了什么?
java·开发语言·javascript
有位神秘人6 小时前
kotlin与Java中的单例模式总结
java·单例模式·kotlin
golang学习记6 小时前
IntelliJ IDEA 2025.3 重磅发布:K2 模式全面接管 Kotlin —— 告别 K1,性能飙升 40%!
java·kotlin·intellij-idea
爬山算法6 小时前
Hibernate(89)如何在压力测试中使用Hibernate?
java·压力测试·hibernate
仟濹6 小时前
算法打卡day2 (2026-02-07 周五) | 算法: DFS | 3_卡码网99_计数孤岛_DFS
算法·深度优先
驭渊的小故事6 小时前
简单模板笔记
数据结构·笔记·算法
YuTaoShao6 小时前
【LeetCode 每日一题】1653. 使字符串平衡的最少删除次数——(解法一)前后缀分解
算法·leetcode·职场和发展