Leetcode 239.滑动窗口最大值
滑动窗口最大值
给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口 k 内的数字。滑动窗口每次只向右移动一位。
返回滑动窗口最大值。
示例:
输入: 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
注意:
你可以假设 k 总是有效的,1 ≤ k ≤ 输入数组的大小,且输入数组不为空。
进阶:
你能在线性时间复杂度内解决此题吗?
思路
维护一个大小为K的最大堆,依此维护一个大小为K的窗口,每次读入一个新数,都把堆中窗口最左边的数扔掉,再把新数加入堆中,这样堆顶就是这个窗口内最大的值。
注意
-结果数组的大小是nums.length + 1 - k, 赋值时下标也是i + 1 - k
import java.util.Collections;
import java.util.PriorityQueue; public class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums == null || nums.length == 0) return new int[0];
PriorityQueue<Integer> pq = new PriorityQueue<Integer>(Collections.reverseOrder());
int[] res = new int[nums.length + 1 - k];
for(int i = 0; i < nums.length; i++){
// 把窗口最左边的数去掉
if(i >= k) pq.remove(nums[i - k]);
// 把新的数加入窗口的堆中
pq.offer(nums[i]);
// 堆顶就是窗口的最大值
if(i + 1 >= k) res[i + 1 - k] = pq.peek();
}
return res;
}
}
双向队列
复杂度
时间 O(N) 空间 O(K)
思路
我们用双向队列可以在O(N)时间内解决这题。当我们遇到新的数时,将新的数和双向队列的末尾比较,如果末尾比新数小,则把末尾扔掉,直到该队列的末尾比新数大或者队列为空的时候才住手。这样,我们可以保证队列里的元素是从头到尾降序的,由于队列里只有窗口内的数,所以他们其实就是窗口内第一大,第二大,第三大...的数。保持队列里只有窗口内数的方法和上个解法一样,也是每来一个新的把窗口最左边的扔掉,然后把新的加进去。然而由于我们在加新数的时候,已经把很多没用的数给扔了,这样队列头部的数并不一定是窗口最左边的数。这里的技巧是,我们队列中存的是那个数在原数组中的下标,这样我们既可以直到这个数的值,也可以知道该数是不是窗口最左边的数。这里为什么时间复杂度是O(N)呢?因为每个数只可能被操作最多两次,一次是加入队列的时候,一次是因为有别的更大数在后面,所以被扔掉,或者因为出了窗口而被扔掉。
public class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums == null || nums.length == 0) return new int[0];
LinkedList<Integer> deque = new LinkedList<Integer>();
int[] res = new int[nums.length + 1 - k];
for(int i = 0; i < nums.length; i++){
// 每当新数进来时,如果发现队列头部的数的下标,是窗口最左边数的下标,则扔掉
if(!deque.isEmpty() && deque.peekFirst() == i - k) deque.poll();
// 把队列尾部所有比新数小的都扔掉,保证队列是降序的
while(!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) deque.removeLast();
// 加入新数
deque.offerLast(i);
// 队列头部就是该窗口内第一大的
if((i + 1) >= k) res[i + 1 - k] = nums[deque.peek()];
}
return res;
}
}
Leetcode 239.滑动窗口最大值的更多相关文章
- Java实现 LeetCode 239 滑动窗口最大值
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 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以 ...
- 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 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 进 ...
随机推荐
- 牛客国庆集训派对Day_4~6
Day_4 A.深度学习 题目描述 小 A 最近在研究深度学习,他自己搭建了一个很牛逼的神经网络,现在他手头一共有 n 组训练数据,一开始他会给自己的神经网络设置一个 batch size,假设为 B ...
- Linux常用命令awk
awk能够处理类似csv这种按行格式的数据,对每一行record按照-F指定的分隔符切割,然后处理.默认支持空格和\t分隔符 1.统计文件里某一列数据等于某个值的个数 -0_djt10.txt 2.拼 ...
- 【ADO.NET】 基础 (SQL Server)
一.Web.config配置 <connectionStrings> <add name="constr_name" connectionString=" ...
- ASP.NET MVC Identity 兩個多個連接字符串問題解決一例
按照ASP.NET MVC Identity建立了一個用戶權限管理模塊,由于還要加自己已有的數據庫,所以建立了一個實體模型,建立了之后,發現登錄不了: 一直顯示“Login in failed for ...
- placeholder字体样式及兼容
样式修改css::-webkit-input-placeholder { /* WebKit browsers */ color: #fff!important;}:-moz-placeholder ...
- mysql单向自动同步
mysql自动同步 以下教程均使用mysql自带的自动同步功能 全库单向自动同步 本例把192.168.3.45上名称为ewater_main的数据库自动同步到192.168.3.68的ewater_ ...
- EXCEL Skills Commonly Used
1. 判断某一列中的数据是否在另一列中 http://jingyan.baidu.com/article/358570f67fd4b0ce4724fc29.html 2. 快速删除excel中的空格( ...
- Idea maven项目不能新建package和class的解决方法
如下图,用IDEA新建的maven项目不能新建package,class等 原因是:这里的java文件夹是普通文件夹,要设置为Sources Root.(如下图) 就可以了(见下图)
- 使用jave2将音频wav转换成mp3格式
最近需要用到语音合成功能,网上查阅了一番,发现可以使用腾讯云的语音合成API来完成这个功能,但是腾讯云的api返回的是wav格式的音频文件,这个格式的文件有些不通用,因此需要转换成mp3格式的文件. ...
- LayuiAdmin退出模块报错解决
将layuiAdmin/src/controller目录下的common.js中 logout方法的url中logout.js的路径修改为自己目录的路径: 我这里修改为绝对路径: