【原创】leetCodeOj --- Sliding Window Maximum 解题报告
天,这题我已经没有底气高呼“水”了。。。
题目的地址:
https://leetcode.com/problems/sliding-window-maximum/
题目内容:
Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.
For example,
Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.
Window position Max
--------------- -----
[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
Therefore, return the max sliding window as [3,3,5,5,6,7].
Note:
You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array.
Follow up:
Could you solve it in linear time?
题目解析:
关键是线性时间。开头我试图通过动态规划定义子问题来解决,然而这并没有什么卵用,怀疑自己已经患上了一定程度的动态规划病,需要重读CLRS回炉一番
其实有第二个关键点。均摊复杂度和严格复杂度,对于“线性时间内解决”这个要求而言,并没有什么不同的地方。
第三个关键点,就是这是一个动态维护的队列,你要在不重新遍历队中元素的情况下维护一个最值。
不知道各位是否做过O(1)时间内维护一个栈中最值的问题,如果没有,可以看看这篇老文:
【原创】leetCodeOj --- Min Stack 解题报告
那位说了,刚才还讲本质上是动态队列,现在你拿栈出来坑蒙拐骗,放学别走
别急别急,不是还能用栈模拟队列吗?
两个栈,队列的push操作,就把元素压到栈1。队列的pop操作,首先检查栈2是否非空,若栈2有元素,直接pop。若栈2无元素,则把当前栈1中全部的元素压进栈2。
这样,我们能够维护一个栈中的最值,就能维护一个队列中的最值。
因为当前队列中的全部元素都分布在这两个栈中,因此,这两个栈的最值再比一轮,就是最后的最值。
又有人问了,pop一次,栈2有东西还好,若没有,就得捣腾半天,把栈1的元素挨个压进栈2,这算哪门子线性时间?
还真是线性时间,别忘了均摊复杂度
每个元素,进队被压进一次栈1,出队时被压进栈2一次,算上弹出操作2次,一共只有4次操作。
一共n个元素
那就是4n个操作
不就是线性吗?
关键在于,一次实际的操作可能只有弹出一次,而压栈的操作被集成在某次弹出时集中执行了。
具体代码:
public class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums.length == 0) {
return nums;
}
int[] res = new int[nums.length - k + 1];
MinQueue queue = new MinQueue();
for (int i = 0; i < k; i ++) {
queue.push(nums[i]);
}
res[0] = queue.getMax();
int index = 1;
for (int i = k; i < nums.length; i ++) {
queue.pop();
queue.push(nums[i]);
res[index ++] = queue.getMax();
}
return res;
}
class MinQueue {
LinkedList<Integer> stack1 = new LinkedList<Integer>();
LinkedList<Integer> stack2 = new LinkedList<Integer>();
LinkedList<Integer> maxOne = new LinkedList<Integer>();
LinkedList<Integer> maxTwo = new LinkedList<Integer>();
public void push(Integer item) {
pushOne(item);
}
public Integer pop() {
Integer res = null;
if (stack2.size() == 0) {
while (stack1.size() != 0) {
pushTwo(popOne());
}
}
res = stack2.pop();
maxTwo.pop();
return res;
}
public Integer getMax() {
Integer one = maxOne.peek();
Integer two = maxTwo.peek();
if (one == null) {
return two;
} else if (two == null){
return one;
}
return one > two ? one : two;
}
private Integer popOne() {
Integer res = null;
maxOne.pop();
res = stack1.pop();
return res;
}
private void pushOne(Integer item) {
stack1.push(item);
if (stack1.size() == 1) {
maxOne.push(item);
} else {
Integer front = maxOne.peek();
if (front < item) {
maxOne.push(item);
} else {
maxOne.push(front);
}
}
}
private void pushTwo(Integer item) {
stack2.push(item);
if (stack2.size() == 1) {
maxTwo.push(item);
} else {
Integer front = maxTwo.peek();
if (front < item) {
maxTwo.push(item);
} else {
maxTwo.push(front);
}
}
}
}
}
【原创】leetCodeOj --- Sliding Window Maximum 解题报告的更多相关文章
- 【LeetCode】239. Sliding Window Maximum 解题报告(Python&C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 单调递减队列 MultiSet 日期 题目地址:ht ...
- 【原创】Sliding Window Maximum 解法分析
这道题是lintcode上的一道题,当然leetcode上同样有. 本题需要寻找O(N)复杂度的算法. 解体思路比较有特点,所以容易想到参考 最小栈 的解题办法. 但是最小栈用栈维护最小值很直观,这道 ...
- leetcode面试准备:Sliding Window Maximum
leetcode面试准备:Sliding Window Maximum 1 题目 Given an array nums, there is a sliding window of size k wh ...
- 【LeetCode】239. Sliding Window Maximum
Sliding Window Maximum Given an array nums, there is a sliding window of size k which is moving fr ...
- 【刷题-LeetCode】239. Sliding Window Maximum
Sliding Window Maximum Given an array nums, there is a sliding window of size k which is moving from ...
- [LeetCode] Sliding Window Maximum 滑动窗口最大值
Given an array nums, there is a sliding window of size k which is moving from the very left of the a ...
- Sliding Window Maximum 解答
Question Given an array of n integer with duplicate number, and a moving window(size k), move the wi ...
- Sliding Window Maximum
(http://leetcode.com/2011/01/sliding-window-maximum.html) A long array A[] is given to you. There is ...
- [Swift]LeetCode239. 滑动窗口最大值 | Sliding Window Maximum
Given an array nums, there is a sliding window of size k which is moving from the very left of the a ...
随机推荐
- ubuntu12.10下arm-linux-gcc交叉编译环境的搭建
交叉编译环境搭建的原因:通俗上讲,因为嵌入式系统可用资源比较少:几十M的ARM 二三百M的flash相对我们的pc机来说资源真的没法比.所以,为了解决这种局面就将PC机等作为主机,搭建开发环境,进行编 ...
- css js 优化工具
我知道国内很多网页制作人员都还在制作table式网页,这样的网页打开速度很慢.如果要想网站打开速度快,就要学会使用DIV+CSS,将图片写进CSS,这样如果网站内容很多的时候,也不会影响网页的浏览.它 ...
- Js实现select联动,option从数据库中读取
待要实现的功能:页面有两个select下拉列表,从第一个select中选择后,在第二个select中出现对应的列表选择,再从第二个select中选择后,在一个text中显示对应的信息.两个select ...
- 利用WinDbg找出程序崩溃的代码行号
之前碰到论坛里有几个好友,说程序不时的崩溃,什么xxoo不能read的! 如果光要是这个内存地址,估计你会疯掉~~ 所以分享一下基本的调试技巧,需要准备的工具有WinDbg + VC6.0, 下面是自 ...
- 《Head First 设计模式》学习笔记——模板方法模式
模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以详细方法以及详细构造函数的形式实现.然后声明一些抽象方法来迫使子类实现剩余的逻辑.不同的子类能够以不同的方式实现这些抽象方法,从而对剩余的逻辑有 ...
- Static关键字的作用及使用
1.使用static声明属性 如果希望一个属性被所有对象共同拥有,可以将其声明为static类型. 声明为static类型的属性或方法,此属性或方法也被称为类方法,可以由类名直接调用. class P ...
- PS中模式算法
详见地址:http://www.68ps.com/zt/cs5/hh_zhengpian.htm
- 基于AdaBoost的人脸检测
原地址:http://blog.csdn.net/celerychen2009/article/details/8839097 人脸检测和人脸识别都是属于典型的机器学习的方法,但是他们使用的方法却相差 ...
- 使用和制作patch文件
使用和制作patch文件 发表时间: 2007-2-13 20:57 作者: superuser 来源: 迷茫人 字体: 小 中 大 | 打印 原文http://www.linuxsir. ...
- 持续集成环境Jenkins的搭建和使用
这几天试着搭了个持续集成环境,我使用的是Jenkins,它的前身是Hadson,由于被Oracle收购了,所以换个名字继续开源,这个有点像MySQL. 持续集成总是跟敏捷开发什么的搞在一起,显得非常高 ...