【算法】单调队列 - 基础与应用-滑动窗口最大值

题目

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

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

思路

暴力:遍历一遍的过程中每次从窗口找到最大的数组,O(n * k)

需要一个队列,在这个队列中放进窗口里的元素,然后随着窗口的移动,队列也一进一出,每次移动后,队列告诉我们里面的最大值是什么。

单调队列,即单调递减或单调递增的队列

保存队列中的元素单调递增或者单调递减,需要自己去实现这个单调队列。

java中使用 Deque deque = new LinkedList<>(); 实现队列

使用Deque自定义一个单调队列插入,弹出,获取一个元素。

  1. 将前k个元素放入单调队列中,取出第一个最大元素
  2. 遍历接下来的数组元素,尝试将窗口中即将被移除的元素从单调队列弹出
  3. 尝试将进入窗口中的元素加入到单调队列
  4. 取出单调队列的最大值,即第一个元素,保存到数组中

始终维护了一个单调的队列,从而每次很容易得取出当前窗口中得最大值。

java 复制代码
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
     
     int n = nums.length;
     int j = 0;
     //存放结果
     int[] res = new int[n - k + 1];
     
    CustomQueue queue = new CustomQueue();

     //先将数组前k的元素放入自定义单调队列中
     for(int i = 0 ; i < k ; i++){
        queue.add(nums[i]);
     }
    
     res[j++] = queue.getMaxValue();

     //遍历数组   i始终是位于滑动窗口最右边
     for(int i = k ; i < n ; i++){
        
         //1.滑动窗口中被移除的元素在单调队列尝试弹出
         queue.poll(nums[i-k]);
         //2.滑动窗口中新加入的元素在单调队列中尝试加入
         queue.add(nums[i]);
         //3.记录当前滑动窗口最大值
         res[j++] = queue.getMaxValue();
     
     }  

     return res;
    }
}


//自定义单调队列
class CustomQueue{
   
  Deque<Integer> deque = new LinkedList<>();

   //弹出元素,如果出口元素和滑动窗口的值一样则弹出
   public void poll(int val){
    if(!deque.isEmpty() && val == deque.peekFirst()){
        deque.pollFirst();
    }
   }
   
   //放入元素.如果入口元素的值小于滑动窗口的值,则弹出入口元素,直到满足为止
   public void add(int val){
    while(!deque.isEmpty() && deque.peekLast() < val){
        deque.pollLast();
    }

    deque.addLast(val); 
   }

   //获取单调队列中最大值
   public int getMaxValue(){
    return deque.peekFirst();
   }

}
相关推荐
_Evan_Yao1 小时前
Redis 缓存穿透、击穿、雪崩,一次讲清!
java·spring·mybatis
梓豪csd1 小时前
消息订阅中心:谁该收到哪条通知
java·开发语言·人工智能·低代码·自动化·1024程序员节
秋饼1 小时前
Spring AI 2.1 Message Parts 深度实战:推理签名回放与跨轮记忆持久化的源码级落地
java·ai·技术分享·后端开发
BK贝壳2 小时前
bool-hybrid-array 落盘我只认 .bha:用 Create_BHA / Ask_BHA 做布尔数组序列化
数据结构·python·numpy·1024程序员节
thefool1122662 小时前
TCP 1
java·1024程序员节
企业数字化笔记4 小时前
视频人体姿态怎么做三维可视化?2D关键点、深度局限与技术选型
人工智能·算法·音视频
金銀銅鐵5 小时前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(下)
java·后端·ai编程
?abc!5 小时前
(数组)581. 最短无序连续子数组
数据结构·算法·leetcode
AI人工智能+电脑小能手5 小时前
一次请求打几个下游,这个Java并行任务工具类6个方法按序聚合
java·线程池·并发编程·1024程序员节·批量处理·并行任务
paopaokaka_luck7 小时前
心理咨询管理系统(WebSocket实时沟通、基于用户的协同过滤、 ECharts多维分析、 预约业务流程、预约校验与定时处理)
java·vue.js·spring boot·mysql·spring·echarts·1024程序员节