题目

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

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

示例 1:

输入:nums = [1,3,-1,-3,5,3,6,7], k = 3

输出:[3,3,5,5,6,7]

解释:

滑动窗口的位置                   最大值
--------------------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7

示例 2:

输入:nums = [1], k = 1

输出:[1]

提示:

1 <= nums.length <= 105
-104 <= nums[i] <= 104
1 <= k <= nums.length

来源:力扣(LeetCode)

链接:https://leetcode.cn/problems/sliding-window-maximum

题解

三种解法

这个题可以有三个解析的方法:

  1. 暴力解法:遍历数组,在每个窗口遍历找到最大值;
  2. 对窗口内容排序。使用一个数据结构记录窗口的内容,每次滑动窗口时,删除离开窗口的元素、新增加入窗口的元素,并维护数据结构内元素的顺序。
    • 可使用大顶堆、BST记录窗口内的内容
  3. 使用单调队列

文章只对使用单调队列的解法进行讲解。

“单调队列”解法

推荐讲解视频:花花酱 LeetCode 239. Sliding Window Maximum - 刷题找工作 EP159-哔哩哔哩

新增、获取最大值

想象有这样的一个queue,queue内的数据是单调递减的。那么,我们只需要获取queue的front就能获取到最大的元素。

每次向这个queue新增元素的时候,queue中的元素在数组中的位置肯定比当前元素更靠前。所以,如果queue中已有的一些元素,它们的值小于新增的元素,则它们肯定不会成为当前窗口(及后续窗口)中的最大值。

所以我们就可以把这些元素pop掉了。

每个新增的元素都是经过如上判断及操作的话,那么这个queue就是一个单调递减的queue了。留在queue中的元素是:1.当前窗口中的最大值;2.后续窗口中可能的最大值。

删除

当窗口滑过了元素的时候,就应该删除该元素。

经过前面的分析,我们知道如果滑出窗口的元素不是queue的max value的话,那说明窗口中该元素之后肯定有更大的元素成为了max value。那么这种情况下,“滑出窗口的元素”肯定已经在这个max value的元素加入到queue的时候已经被pop了。

所以我们只需要判断max value是否等于“滑出窗口的元素”,如果等于则pop front。

代码


public int[] maxSlidingWindow(int[] nums, int k) {
if (nums.length < k) {
return null;
} int[] result = new int[nums.length - k + 1];
int resultIndex = 0; // 第一个窗口(前k个元素)
MonotonicQueue monotonicQueue = new MonotonicQueue();
for (int i = 0; i < k; i++) {
monotonicQueue.push(nums[i]);
}
result[resultIndex++] = monotonicQueue.max(); // 随后的窗口
for (int i = k; i < nums.length; i++) {
if (nums[i - k] == monotonicQueue.max()) {
monotonicQueue.pop();
}
monotonicQueue.push(nums[i]);
result[resultIndex++] = monotonicQueue.max();
} return result;
} /**
* 单调Queue,first大、last小
*/
private static class MonotonicQueue { private final Deque<Integer> deque; public MonotonicQueue() {
deque = new LinkedList<>();
} public void pop() {
deque.pollFirst();
} public void push(Integer num) {
while (!deque.isEmpty() && num > deque.getLast()) {
deque.removeLast();
}
deque.offerLast(num);
} public Integer max() {
return deque.getFirst();
} }

【leetcode】239. 滑动窗口最大值的更多相关文章

  1. Java实现 LeetCode 239 滑动窗口最大值

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

  2. Leetcode 239.滑动窗口最大值

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

  3. 【leetcode 239. 滑动窗口最大值】解题报告

    思路:滑动窗口的思想,只要是求连续子序列或者子串问题,都可用滑动窗口的思想 方法一: vector<int> maxSlidingWindow(vector<int>& ...

  4. leetcode 239. 滑动窗口最大值(python)

    1. 题目描述 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 示 ...

  5. 代码随想录第十三天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素

    第一题150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. ...

  6. LeetCode(239.滑动窗口的最大值

    题目: 给定一个数组nums,有一个大小为k的滑动窗口从数组的最左侧移动到最右侧,你只可以看到滑动窗口内的k个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 示例: 输入: nums = ...

  7. leetcode全部滑动窗口题目总结C++写法(完结)

    3. 无重复字符的最长子串 A: 要找最长的无重复子串,所以用一个map保存出现过的字符,并且维持一个窗口,用le和ri指针标识.ri为当前要遍历的字符,如果ri字符在map中出现过,那么将le字符从 ...

  8. [Leetcode]双项队列解决滑动窗口最大值难题

    这道题是从优先队列的难题里面找到的一个题目.可是解法并不是优先队列,而是双项队列deque 其实只要知道思路,这一道题直接写没有太大的问题.我们看看题 给定一个数组 nums,有一个大小为 k 的滑动 ...

  9. LeetCoded第239题题解--滑动窗口最大值

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

随机推荐

  1. Pycharm使用 Ctrl+滚轮 调整字体大小

    首先,打开File中的Settings 然后,点开Editor内的General 最后,在3 指向的位置勾选:Change font size (Zoom)with Ctrl+Mouse Whel 这 ...

  2. Cadence 错误合集

    1.原理图DRC出现如下错误"Duplicate Pin Name "GND" found on Packag" 解决方案:原因是元件引脚重复定义,可以进行重新 ...

  3. 在原生CSS中使用变量

    本文首发于我的博客 一直以来,CSS作为一种申明式的样式标记语言,很难像如javascript等命令式编程语言一样通过定义和使用变量的方式来维护和追踪某些状态.后来随着scss,less等CSS预处理 ...

  4. Kurento安装与入门02——运行示例前的准备

    官方一共提供了13个示例,这些示例运行的方式大同小异,一般会提供JAVA.Browser JavaScript.Node.js三种版本,这里仅演示java版本的示例.这些示例要求系统内已经正确安装了K ...

  5. 破解浏览器同源政策利器之JSONP

    本文是在了解了浏览器的同源规则之后,学习了破解这个规则的一个简单有效的方法->JSONP.主要通过阮一峰老师的博客学习 浏览器的同源规则 有这样一个背景,如果你通过银行的网站进行的取钱的交易,而 ...

  6. pip freeze > requirements.txt` 命令输出文件中出现文件路径而非版本号

    pip freeze > requirements.txt 命令输出文件中出现文件路径而非版本号 解决办法: pip list --format=freeze > requirements ...

  7. 小程序colorui框架引入与使用

    colorui是UI框架:   超好用的一款 小程序二维码体验: :  引入方式: 1.先去下载colorui     https://github.com/weilanwl/ColorUI 把col ...

  8. openlayer路线箭头

    // 用于设置线串所在的矢量图层样式的函数 var styleFunction = function(feature,res){ //轨迹线图形 var trackLine= feature.getG ...

  9. macos停止MySQL服务

    1.命令行中 使用 find /usr  -name mysql 查找自己电脑中MySQL的安装位置 例如我查找到我电脑MySQL安装位置是 /usr/local/Cellar/mysql@5.6/5 ...

  10. 使用JQGrid中可见列并存入Cookie

    引入js与css <link href="~/Content/js/jquery-ui/jquery-ui.min.css" rel="stylesheet&quo ...