• LeetCode239. 滑动窗口最大值


    题目

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

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

    分析

    求每个窗口内部的最大值问题,就等同于求连续特定区间内部的最大值最小值问题,这就是单调队列的应用之一。

    单调队列用双端队列实现。常用的queue在没有指定容器的条件下,用的底层就是双端队列。注意:单调队列不是并不是优先级队列,保存了所有的元素。它只保留可能成为最大(小)元素。

    设计单调(递减)队列的规则:

    1. 如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作

    2.如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止

    上面是代码随想录的Carl大佬总结。

    代码

     1 class Solution {
     2 private:
     3 //单调队列,用dequeue实现从大到小
     4 class MyQueue{
     5 public:
     6     deque<int>que;
     7 
     8     //每次需要弹出元素,要与单调队列开头元素比较,如果和开头元素相同,则弹出
     9     //否则,不做任何操作
    10     void pop(int x){
    11         if(!que.empty() && x == que.front()){
    12             que.pop_front(); //从双端队列头部弹出,该元素是最大元素
    13         }
    14     }
    15 
    16     //每次需要进入元素,要与单调队列尾部部元素进行比较。
    17     //如果要进入元素比单调队列元素的值大,就将单调队列中小于要进入的元素从队列尾部弹出
    18     //直到push的值小于等于单调队列元素为止。这样就保持了单调递减的性质
    19     void push(int x){
    20         while(!que.empty() && x > que.back()){
    21             que.pop_back();
    22         }
    23         que.push_back(x);//从队列尾部加入元素x
    24     }
    25     int front(){
    26         return que.front();
    27     }
    28 };
    29 public:
    30     vector<int> maxSlidingWindow(vector<int>& nums, int k) {
    31         MyQueue que;
    32         vector<int>res;
    33         //首先将前k个加入单调队列
    34         for(int i = 0;i < k;i++){
    35             que.push(nums[i]);
    36         }
    37         res.push_back(que.front());
    38         //开始进行窗口滑动,窗口每向前移动一次,窗口要移除元素,加入元素
    39         //并且返回单调队列的头部元素(保存了最大值)加入res
    40         for(int i = k;i < nums.size();i++){
    41             que.pop(nums[i - k]); //窗口移除元素
    42             que.push(nums[i]);//窗口加入元素
    43             res.push_back(que.front());
    44         }
    45         return res;
    46 
    47     }
    48 };

    时间复杂度O(n),空间复杂度O(k)

  • 相关阅读:
    bzoj 1761: [Baltic2009]beetle 区间dp
    NOI冲刺计划
    bzoj 2107: Spoj2832 Find The Determinant III 辗转相除法
    bzoj 2482: [Spoj GSS2] Can you answer these queries II 线段树
    bzoj 1209: [HNOI2004]最佳包裹 三维凸包
    SCOI2015题解 && 考试小结
    bzoj 2806: [Ctsc2012]Cheat 后缀自动机DP
    考场上应该想到。。。。
    spoj LCS 后缀自动机
    BZOJ 1639: [Usaco2007 Mar]Monthly Expense 月度开支
  • 原文地址:https://www.cnblogs.com/fresh-coder/p/14336594.html
Copyright © 2020-2023  润新知