Java 滑动窗口最大值的实现

一、题目

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回滑动窗口中的最大值。

二、单调队列解析

题目让求随着滑动窗口的滑动,返回窗口覆盖范围的最大值

该题不适合优先级队列,因为采用大顶堆存放k个数字,可以知道此时的最大值,但是窗口是滑动的,大顶堆每次只能弹出最大值,无法移除其他值,即无法用大顶堆维护滑动窗口里的值。

所以采用队列维护,随着窗口的移动,队列先进先出

此时对队列的要求是,队列首位为最大值,整个队列呈递减
例如:1,3,-1,-3,5,3,6,7

初始:1,3,-1,队列存入3,-1,使其保持递减,且首位为此时滑动窗口的最大值
移动到-3,队列:3,-1,-3
移动到5,队列:5
移动到3,队列:5,3
移动到6,队列:6
移动到7,队列:7

所以为了满足要求,需要自定义队列

从示例可以看出,队列没必要维护窗口里所有元素,只需要保证队列首位此时窗口的最大,而且,队列元素为递减,具体看代码

三、代码

import java.util.Deque;
import java.util.LinkedList;
//自定义数组
class MyQueue {
    Deque<Integer> deque = new LinkedList<>();
    //弹出元素时,比较当前要弹出的数值是否等于队列出口的数值,如果相等则弹出
    //同时判断队列当前是否为空
    void poll(int val) {
        if (!deque.isEmpty() && val == deque.peek()) {
            deque.poll();
        }
    }
    //添加元素时,如果要添加的元素大于入口处的元素,就将入口元素弹出
    //保证队列元素单调递减
    //比如此时队列元素3,1,2将要入队,比1大,所以1弹出,此时队列:3,2
    void add(int val) {
        while (!deque.isEmpty() && val > deque.getLast()) {
            deque.removeLast();
        }
        deque.add(val);
    }
    //队列队顶元素始终为最大值
    int peek() {
        return deque.peek();
    }
}

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if (nums.length == 1) {
            return nums;
        }
        int len = nums.length - k + 1;
        //存放结果元素的数组
        int[] res = new int[len];
        int num = 0;
        //自定义队列
        MyQueue myQueue = new MyQueue();
        //先将前k的元素放入队列
        for (int i = 0; i < k; i++) {
            myQueue.add(nums[i]);
        }
        res[num++] = myQueue.peek();
        for (int i = k; i < nums.length; i++) {
            //滑动窗口移除最前面的元素,移除是判断该元素是否放入队列
            myQueue.poll(nums[i - k]);
            //滑动窗口加入最后面的元素
            myQueue.add(nums[i]);
            //记录对应的最大值
            res[num++] = myQueue.peek();
        }
        return res;
    }
}

四、总结

该题利用了单调队列,需要自己定义入队出队规则

入队:保持队首元素始终最大,同时队内维护窗口的大小个元素,呈现递减

出队:判断当前元素是否入队,在队内,再随着窗口的滑动执行出队操作

到此这篇关于Java 滑动窗口最大值的实现的文章就介绍到这了,更多相关Java 滑动窗口最大值内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java 实现滑动时间窗口限流算法的代码

    在网上搜滑动时间窗口限流算法,大多都太复杂了,本人实现了个简单的,先上代码: package cn.dijia478.util; import java.time.LocalTime; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; /** * 滑动时间窗

  • Java 滑动窗口最大值的实现

    一.题目 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 二.单调队列解析 题目让求随着滑动窗口的滑动,返回窗口覆盖范围的最大值 该题不适合优先级队列,因为采用大顶堆存放k个数字,可以知道此时的最大值,但是窗口是滑动的,大顶堆每次只能弹出最大值,无法移除其他值,即无法用大顶堆维护滑动窗口里的值. 所以采用队列维护,随着窗口的移动,队列先进先出 此时对队列的要求

  • Java C++分别实现滑动窗口的最大值

    目录 1.题目 2.思路 3.c++代码 4.java代码 1.题目 给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值. 示例: 提示: 你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小. 2.思路 (单调队列) O(n) 给定一个数组 nums 和滑动窗口的大小 k,让我们找出所有滑动窗口里的最大值. 样例: 如样例所示,nums = [1,3,-1,-3,5,3,6,7],k = 3,我们输出[3,3,5,5,6,7]. 首先,我

  • JavaScript日拱算法题解滑动窗口的最大值示例

    目录 题目: 题解: 第一反应 JavaScript 实现 第二反应 JS 实现 小结: 题目: 给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值. 示例: 输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3 输出: [3,3,5,5,6,7] 解释: 滑动窗口的位置 最大值 --------------- ----- [1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -3 5] 3 6

  • 分享几道和「滑动窗口」有关的算法面试题

    前言科普:什么是滑动窗口算法 滑动问题包含一个滑动窗口,它是一个运行在一个大数组上的子列表,该数组是一个底层元素集合. 假设有数组 [a b c d e f g h ],一个大小为 3 的 滑动窗口 在其上滑动,则有: [a b c] [b c d] [c d e] [d e f] [e f g] [f g h] 一般情况下就是使用这个窗口在数组的 合法区间 内进行滑动,同时 动态地 记录一些有用的数据,很多情况下,能够极大地提高算法地效率. 1. 滑动窗口最大值 题目来源于 LeetCode

  • redis zset实现滑动窗口限流的代码

    目录 限流 rediszset特性 滑动窗口算法 java代码实现 补充:RediszSet实现滑动窗口对短信进行防刷限流 前言 示例代码 限流 需求背景:同一用户1分钟内登录失败次数超过3次,页面添加验证码登录验证,也即是限流的思想. 常见的限流算法:固定窗口计数器:滑动窗口计数器:漏桶:令牌桶.本篇选择的滑动窗口计数器 redis zset特性 Redis 有序集合(sorted set)和集合(set)一样也是 string 类型元素的集合,且不允许重复的成员.不同的是每个元素都会关联一个

  • Java Flink窗口触发器Trigger的用法详解

    目录 定义 Trigger 源码 TriggerResult 源码 Flink 预置的Trigger EventTimeTrigger源码 ProcessingTimeTrigger源码 常见窗口的Trigger 滚动窗口 滑动窗口 会话窗口 全局窗口 定义 Trigger确定窗口(由窗口分配器形成)何时准备好由窗口函数处理.每个WindowAssigner都带有一个默认值Trigger.如果默认触发器不符合您的需求,您可以使用trigger(…). Trigger 源码 public abst

  • jQuery实现仿微软首页感应鼠标变化滑动窗口效果

    本文实例讲述了jQuery实现仿微软首页感应鼠标变化滑动窗口效果.分享给大家供大家参考.具体如下: 这是一款jQuery仿微软首页感应鼠标变化的滑动窗口,鼠标放上后,窗口会向左拉长,鼠标移走后恢复原样,是在微软官方网站发现的,看了看代码,觉得很容易就扣下来,不敢独享. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/jquery-f-microsoft-web-nav-demo/ 具体代码如下: <!DOCTYPE html PUBLIC "

  • Java多线程窗口售票问题实例

    本文介绍了多线程实现多个窗口售票问题的两种枷锁方式, 分别是synchronized 和lock()和unlock() 具体代码如下: 第一种: package Runnable; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /* * 同步 * 这里有两种方式加锁 * 分别是 * 1.synchronized * 2.lock()和unlock() */ publ

  • Java中求最大值的4种方法实例代码

    前言 本文主要给大家分享了关于java求最大值的4中方法,文中给出了完整的示例代码,下面话不多少了,来一起看看吧 示例代码: /** *@author Prannt *求最大值(或最小值) *本例以int数据类型为例,可指定其他数据类型 */ //方法一:直接法,求最小值类似 public class Deno05ArrayMax { public static void main(String[] args) { //数据类型可指定 int [] array = {5,15,20,30,100

  • go redis实现滑动窗口限流的方式(redis版)

    之前给大家介绍过单机当前进程的滑动窗口限流 , 这一个是使用go redis list结构实现的滑动窗口限流 , 原理都一样 , 但是支持分布式 原理可以参考之前的文章介绍 func LimitFreqs(queueName string, count uint, timeWindow int64) bool { currTime := time.Now().Unix() length := uint(ListLen(queueName)) if length < count { ListPus

随机推荐