Java 滑动窗口最大值的实现

 更新时间:2021年05月21日 10:11:26   作者:南淮北安  
这篇文章主要介绍了Java 滑动窗口最大值,给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。感兴趣的可以了解一下

一、题目

给你一个整数数组 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 滑动窗口最大值内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • idea批量启动多个微服务具体实现

    idea批量启动多个微服务具体实现

    这篇文章主要给大家介绍了关于idea批量启动多个微服务的具体实现,在微服务开发过程中,我们经常要在本地启动很多个微服务,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-07-07
  • spring整合struts2过程详解

    spring整合struts2过程详解

    这篇文章主要介绍了spring整合struts2过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • String s = new String(''a '') 到底产生几个对象

    String s = new String(''a '') 到底产生几个对象

    这篇文章主要介绍了String s = new String(" a ") 到底产生几个对象,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • Idea 配置国内 Maven 源的图文教程

    Idea 配置国内 Maven 源的图文教程

    这篇文章主要介绍了Idea 配置国内 Maven 源的教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-11-11
  • MyBatis Xml映射文件之字符串替换方式

    MyBatis Xml映射文件之字符串替换方式

    这篇文章主要介绍了MyBatis Xml映射文件之字符串替换方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • springcloud检索中间件 ElasticSearch 分布式场景的使用

    springcloud检索中间件 ElasticSearch 分布式场景的使用

    单机的elasticsearch做数据存储,必然面临两个问题:海量数据存储问题、单点故障问题,本文重点给大家介绍springcloud检索中间件 ElasticSearch 分布式场景的运用,感兴趣的朋友跟随小编一起看看吧
    2023-10-10
  • 解决多模块项目中Mybatis的Mapper内部方法找不到的问题

    解决多模块项目中Mybatis的Mapper内部方法找不到的问题

    这篇文章主要介绍了解决多模块项目中Mybatis的Mapper内部方法找不到的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • 如何在SpringBoot+Freemarker中获取项目根目录

    如何在SpringBoot+Freemarker中获取项目根目录

    这篇文章主要介绍了如何在SpringBoot+Freemarker中获取项目根目录的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • 一步步教你整合SSM框架(Spring MVC+Spring+MyBatis)详细教程

    一步步教你整合SSM框架(Spring MVC+Spring+MyBatis)详细教程

    使用SSM(Spring、SpringMVC和Mybatis)已经有段时间了,项目在技术上已经没有什么难点了,基于现有的技术就可以实现想要的功能,下面这篇文章主要给大家介绍了关于整合SSM框架:Spring MVC + Spring + MyBatis的相关资料,需要的朋友可以参考下。
    2017-07-07
  • 详解Java的类加载机制及热部署的原理

    详解Java的类加载机制及热部署的原理

    今天我要讲的就是Java的热部署的原理,由于热部署的原理和类的加载机制有关,所以打算讲一下类加载的机制,文中介绍的非常详细,需要的朋友可以参考下
    2021-05-05

最新评论