• 【单调队列】 239. 滑动窗口最大值


    239. 滑动窗口最大值

    解题思路

    • 计算每一个滑动窗口的最大值 关键在于借助单调队列实现窗口
    • 对于单调队列 尾部添加元素 头部删除元素
    • 添加元素操作:从尾部开始循环对比 删除比当前元素小的元素
    • 获取最大值元素 直接获取头部元素
    • 删除元素操作 直接删除头部元素
    class Solution {
        public int[] maxSlidingWindow(int[] nums, int k) {
                // 借助单调队列  计算每一个滑动窗口的最大值
                MonotonicQueue window = new MonotonicQueue();// 单调队列窗口
                List<Integer> res = new ArrayList<>();
    
    
                for(int i = 0; i < nums.length; i++){
                    if(i < k - 1){
                        window.push(nums[i]);// 先把前面k- 1 个元素填满
                    }else{
                        // 窗口开始向前面移动
                        // 移入新的元素
                        window.push(nums[i]);
    
                        // 因为是单调队列  直接计算最大值
                        res.add(window.max());
    
                        // 移除最后的元素
                        window.pop(nums[i - k + 1]);
                    }
                }
    
                // 将List 类型转换为int[] 数组 作为返回值
                int[] arr = new int[res.size()];
    
                for(int i = 0; i < res.size(); i++){
                    arr[i] = res.get(i);
                }
    
                return arr;
        }
    
        // 单调队列的实现  尾部添加元素   头部删除元素  那么头部元素是最大值
        // 维护的单调队列 是需要从尾部到头部的元素 全部单调递增
        class MonotonicQueue{
            // 使用双链表 模拟队列  支持头部和尾部添加和删除元素
            private LinkedList<Integer> maxq = new LinkedList<>();
    
            public void push(int n){
                // 尾部添加一个元素  需要维护单调队列 从尾部到头部 单调递增的性质
                // 从尾部开始 将前面小于她的元素 全部删除掉  这样维护的就是一个单调队列
                while(!maxq.isEmpty() && maxq.getLast() < n){
                    maxq.pollLast();// 删除尾部元素
                }
                maxq.addLast(n);// 添加元素   尾部添加元素
            }
    
            // 计算最大元素 直接就是取出 头部元素 因为头部元素最大
            public int max(){
                return maxq.getFirst();
            }
    
            // 头部删除元素
            public void pop(int n){
                if(n == maxq.getFirst()){
                    maxq.pollFirst();
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
  • 相关阅读:
    C#入门(10):集合用法介绍
    虾皮网同行数据丨虾皮数据工具-知虾:监控竞争对手数据的利器
    Jenkins实践指南--pipeline概述
    应用架构的演进 | 使用无服务器构建业务弹性
    内容营销专家刘鑫炜:全网简单易上手的品牌打造法教程第二节
    Java#22(内部类)
    JAVA知识管理系统计算机毕业设计Mybatis+系统+数据库+调试部署
    LeetCode讲解篇之77. 组合
    React-18(组件化开发)--ref与react过渡动画
    理解Android中Dialog
  • 原文地址:https://blog.csdn.net/qq_44653420/article/details/133412612