【leetcode】239. 滑动窗口最大值
题目
给你一个整数数组 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
题解
三种解法
这个题可以有三个解析的方法:
- 暴力解法:遍历数组,在每个窗口遍历找到最大值;
- 对窗口内容排序。使用一个数据结构记录窗口的内容,每次滑动窗口时,删除离开窗口的元素、新增加入窗口的元素,并维护数据结构内元素的顺序。
- 可使用大顶堆、BST记录窗口内的内容
- 使用单调队列
文章只对使用单调队列的解法进行讲解。
“单调队列”解法
推荐讲解视频:花花酱 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. 滑动窗口最大值的更多相关文章
- Java实现 LeetCode 239 滑动窗口最大值
239. 滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最 ...
- Leetcode 239.滑动窗口最大值
滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口 k 内的数字.滑动窗口每次只向右移动一位. 返回滑动窗口最大值. 示例: ...
- 【leetcode 239. 滑动窗口最大值】解题报告
思路:滑动窗口的思想,只要是求连续子序列或者子串问题,都可用滑动窗口的思想 方法一: vector<int> maxSlidingWindow(vector<int>& ...
- leetcode 239. 滑动窗口最大值(python)
1. 题目描述 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 示 ...
- 代码随想录第十三天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素
第一题150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. ...
- LeetCode(239.滑动窗口的最大值
题目: 给定一个数组nums,有一个大小为k的滑动窗口从数组的最左侧移动到最右侧,你只可以看到滑动窗口内的k个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 示例: 输入: nums = ...
- leetcode全部滑动窗口题目总结C++写法(完结)
3. 无重复字符的最长子串 A: 要找最长的无重复子串,所以用一个map保存出现过的字符,并且维持一个窗口,用le和ri指针标识.ri为当前要遍历的字符,如果ri字符在map中出现过,那么将le字符从 ...
- [Leetcode]双项队列解决滑动窗口最大值难题
这道题是从优先队列的难题里面找到的一个题目.可是解法并不是优先队列,而是双项队列deque 其实只要知道思路,这一道题直接写没有太大的问题.我们看看题 给定一个数组 nums,有一个大小为 k 的滑动 ...
- LeetCoded第239题题解--滑动窗口最大值
滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 进 ...
随机推荐
- notification(浏览器通知)
一.notification简介 Web Notifications是HTML5 的一个特性,目前我知道的有谷歌浏览器和windows edge对它进行了支持,用于向用户配置和显示桌面通知. 二.no ...
- 前端基础之CSS(1)
1.css3的新特性有哪些 (1)CSS3选择器(基本.属性.伪类具体见下) (2)CSS3边框与圆角 圆角border-radius 属性:border-top-left-radius 左上角 bo ...
- 前端网络安全——前端XSS
XSS攻击:Cross Site Scripting(跨站脚本攻击) XSS攻击原理:程序+数据=结果,如果数据中包含了一部分程序,那么结果就会执行不属于站点的程序. XSS攻击能干什么?能注入Scr ...
- java1.7之后的比较器特别之处
在jdk1.7环境下使用Collectons.sort()方法: 比如:Collections.sort(list, new Comparator<Integer>()); 就可能会出现异 ...
- Map集合的六种遍历方式
学习目标: 熟练掌握Map的遍历方式 例题: 需求:遍历Map集合 代码如下: package com.yy.object.test.test_collection; import java.util ...
- [ Skill ] 为什么 Lisp 语言如此先进
https://www.cnblogs.com/yeungchie/ 网上看到一个应该是 2002 年的文章 译文转自:为什么Lisp语言如此先进?(译文) - 阮一峰的网络日志 原文地址:Reven ...
- 面向对象编程-终结篇 es6新增语法
各位,各位,终于把js完成了一个段落了,这次的章节一过我还没确定下面要学的内容可能是vue也可能是前后端交互,但无论是哪个都挺兴奋的,因为面临着终于可以做点看得过去的大点的案例项目了,先憋住激动地情绪 ...
- python---导入模块和包
导入模块和包 导入模块 import的过程中发生了哪些事情? 寻找模块 如果找到,开辟一块空间,执行这个模块 把这个模块中用到的名字都收录到开辟的空间中 创建一个变量来引用这个模块的空间 注意: 模块 ...
- 微信小程序,制作属于自己的Icon图标
前言 最近在接手一个微信小程序,发现里面的图标都是使用的image组件,看起来非常别扭,加载也不太顺畅. 就想着看看微信有没有类似自带的图标库可以使用. 有是有,就是太少了,翻来翻去好像也就 8 种, ...
- Unity-动画状态机使用细节记录
Unity动画控制器Animator功能非常强大,总结一些具体使用细节,在动作游戏中很实用: 1.动画烘焙 不同动画之间,可能存在角色朝向,重心高度不一致: 可以在动画Eidt界面设置RootTran ...