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)

相关推荐
rchmin3 分钟前
限流算法:令牌桶与漏桶详解
算法·限流
想用offer打牌4 分钟前
一站式了解Spring AI Alibaba的流式输出
java·人工智能·后端
Lonely丶墨轩5 分钟前
从登录入口窥见架构:一个企业级双Token认证系统的深度拆解
java·数据库·sql
leoufung11 分钟前
LeetCode 221:Maximal Square 动态规划详解
算法·leetcode·动态规划
黑符石12 分钟前
【论文研读】Madgwick 姿态滤波算法报告总结
人工智能·算法·机器学习·imu·惯性动捕·madgwick·姿态滤波
源代码•宸15 分钟前
Leetcode—39. 组合总和【中等】
经验分享·算法·leetcode·golang·sort·slices
好易学·数据结构16 分钟前
可视化图解算法77:零钱兑换(兑换零钱)
数据结构·算法·leetcode·动态规划·力扣·牛客网
AlenTech30 分钟前
226. 翻转二叉树 - 力扣(LeetCode)
算法·leetcode·职场和发展
Tisfy33 分钟前
LeetCode 1458.两个子序列的最大点积:动态规划
算法·leetcode·动态规划·题解·dp
求梦82033 分钟前
【力扣hot100题】合并区间(9)
算法·leetcode·职场和发展