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

每次窗口移动的时候,调用que.pop(滑动窗口中移除元素的数值),que.push(滑动窗口添加元素的数值),然后que.front()就返回我们要的最大值。

然后在分析一下,队列里的元素一定是要排序的,而且要最大值放在出队口,要不然怎么知道最大值呢。

但如果把窗口里的元素都放进队列里,窗口移动的时候,队列需要弹出元素。

那么已经排序之后的队列 怎么能把窗口要移除的元素(这个元素可不一定是最大值)弹出呢。

大家此时应该陷入深思…

「其实队列没有必要维护窗口里的所有元素,只需要维护有可能成为窗口里最大值的元素就可以了,同时保证队列里的元素数值是由大到小的。」

那么这个维护元素单调递减的队列就叫做「单调队列,即单调递减或单调递增的队列。C++中没有直接支持单调队列,需要我们自己来一个单调队列」

class Solution {private:class MyQueue { //单调队列(从大到小)public:deque<int> que; // 使用deque来实现单调队列// 每次弹出的时候,判断队列当前是否为空,并比较当前要弹出的数值是否等于队列出口元素的数值,如果相等则弹出。void pop(int value) {if (!que.empty() && value == que.front()) {que.pop_front();}}// 如果push的数值大于入口元素的数值,那么就将队列后端的数值弹出,直到push的数值小于等于队列入口元素的数值为止。 // 这样就保持了队列里的数值是单调从大到小的了。void push(int value) {while (!que.empty() && value > que.back()) {que.pop_back();}que.push_back(value);}// 查询当前队列里的最大值int front() {return que.front();}};
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {MyQueue que;vector<int> result;for (int i = 0; i < k; i++) { // 先将前k的元素放进队列que.push(nums[i]);}result.push_back(que.front()); // result 记录前k的元素的最大值for (int i = k; i < nums.size(); i++) {que.pop(nums[i - k]); // 移除滑动窗口最前面元素que.push(nums[i]);    //向滑动窗口右侧添加元素result.push_back(que.front()); // 记录对应的最大值}return result;}
};

在来看一下时间复杂度,使用单调队列的时间复杂度是 O(n)。

有人可能想了,在队列中 push元素的过程中,还有pop操作呢,感觉不是纯粹的O(n)。

其实,大家可以自己观察一下单调队列的实现,nums 中的每个元素最多也就被 push_back 和 pop_back 各一次,没有任何多余操作,所以整体的复杂度还是 O(n)。

空间复杂度因为我们定义一个辅助队列,所以是O(k)。

滑动窗口最大值--单调队列相关推荐

  1. Sliding Window滑动窗口(单调队列)

    Sliding Window滑动窗口 POJ - 2823 目录 Sliding Window滑动窗口 POJ - 2823 题意描述 解题思路 AC代码 An array of size n ≤ 1 ...

  2. (补)算法训练Day13 | LeetCode150. 逆波兰表达式求值(栈应用);LeetCode239. 滑动窗口最大值(单调队列);LeetCode347. 前K个高频元素(小顶堆,优先级队列)

    目录 LeetCode150. 逆波兰表达式求值 1. 思路 2. 代码实现 3. 复杂度分析 4. 思考 LeetCode239. 滑动窗口最大值 1. 思路 2. 代码实现 3. 复杂度分析 4. ...

  3. Suzy找到实习了吗Day 13 | 栈和队列结束啦 239. 滑动窗口最大值,347. 前 K 个高频元素

    day 13 239. 滑动窗口最大值 Python的Deque模块详解 solution 我复制的,好难不会写 347. 前 K 个高频元素(一刷我没有用栈,用的哈希法) solution(hash ...

  4. 单调区间之239.滑动窗口最大值

    单调区间 239. 滑动窗口最大值 这个题如果用普通的优先队列是有问题的,因为每次弹出去的不知道是上一个窗口的左边界还是这个窗口里的元素.我们要的是每次只弹出上一个窗口的左边界并且还能弹出最值,所以这 ...

  5. 栈和队列6:滑动窗口最大值

    问题描述: 题目链接: 滑动窗口最大值 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. ...

  6. 力扣239. 滑动窗口最大值(自定义排序队列)

    239. 滑动窗口最大值 //实现功能:peek()取得队列的最大值,比最大值先添加进来的删除,后添加进来的保留 class Mydeque{Deque<Integer> deque;pu ...

  7. 【LeetCode】【HOT】239. 滑动窗口最大值(双向队列)

    [LeetCode][HOT]239. 滑动窗口最大值 文章目录 [LeetCode][HOT]239. 滑动窗口最大值 package hot;import java.util.Arrays; im ...

  8. 代码随想录算法训练营day13 | 239. 滑动窗口最大值 | 347.前 K 个高频元素

    一.239. 滑动窗口最大值 from collections import dequeclass MyQueue: #单调队列(从大到小def __init__(self):self.queue = ...

  9. 嗯,查询滑动窗口最大值的这4种方法不错....

    作者 | 王磊 来源 | Java中文社群(ID:javacn666) 转载请联系授权(微信ID:GG_Stone) 本文已收录至 Github<小白学算法>系列:https://gith ...

最新文章

  1. 高并发系统三大利器之限流
  2. 进阶学习(3.11) Facade Pattern 门面模式
  3. IndexedDB技术简介(一)(转)
  4. php常量数组吗,包含数组的PHP常量?
  5. VUE-PDF VUE的PDF预览组件
  6. 调用gensim库训练word2vec词向量
  7. tornado使用mysql 连接池(torndb)
  8. 互联网架构技术干货视频分享地址发布和情况说明
  9. 有哪些值得实力推荐的高评分经典电影,VIP视频解析网站推荐十部
  10. 重置mysql数据库密码_重置mysql数据库密码的方法
  11. Python3.GrADS的二进制码数据
  12. python中如何调取wind数据_Python量化-使用wind接口获取数据
  13. dell r230u盘启动安装2008_利用U盘安装win2008r2系统的步骤
  14. 基于flask实现疫情可视化监控系统
  15. Premiere Pro cc 2019 学习笔记
  16. jQuery基础入门
  17. 如何给纸壳箱上装,#ps修图p图抠图视频教程小白入门基础课程
  18. 亚马逊美国站服装类目需要审核怎么办?亚马逊美国站服装好做吗?
  19. 2008ubuntu主题衣服已经出来了
  20. 股市入门篇——什么是熊市?

热门文章

  1. jquery 设置asp:dropdownlist 选中项
  2. poj 3207 2-sat
  3. 推荐25个非常优秀的网页表单设计案例
  4. C# 关于密码加密 (转载)
  5. 操作系统实验报告13:线程池简单实现
  6. [python应用案例] 一.BeautifulSoup爬取天气信息并发送至QQ邮箱
  7. Putty基础教程之(一).入门命令学习及编写HTML
  8. 【数据结构与算法】之深入解析“等差数列划分”的求解思路与算法示例
  9. 利用Python延迟初始化提升性能
  10. Python eval的用法及注意事项