天,这题我已经没有底气高呼“水”了。。。

题目的地址:

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 解题报告的更多相关文章

  1. 【LeetCode】239. Sliding Window Maximum 解题报告(Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 单调递减队列 MultiSet 日期 题目地址:ht ...

  2. 【原创】Sliding Window Maximum 解法分析

    这道题是lintcode上的一道题,当然leetcode上同样有. 本题需要寻找O(N)复杂度的算法. 解体思路比较有特点,所以容易想到参考 最小栈 的解题办法. 但是最小栈用栈维护最小值很直观,这道 ...

  3. leetcode面试准备:Sliding Window Maximum

    leetcode面试准备:Sliding Window Maximum 1 题目 Given an array nums, there is a sliding window of size k wh ...

  4. 【LeetCode】239. Sliding Window Maximum

    Sliding Window Maximum   Given an array nums, there is a sliding window of size k which is moving fr ...

  5. 【刷题-LeetCode】239. Sliding Window Maximum

    Sliding Window Maximum Given an array nums, there is a sliding window of size k which is moving from ...

  6. [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 ...

  7. Sliding Window Maximum 解答

    Question Given an array of n integer with duplicate number, and a moving window(size k), move the wi ...

  8. Sliding Window Maximum

    (http://leetcode.com/2011/01/sliding-window-maximum.html) A long array A[] is given to you. There is ...

  9. [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 ...

随机推荐

  1. Delphi调用C++导出的QT类

    打开VS2008创建一个dll项目(创建了一个QT Library项目),新建头文件q4dapplication.h定义纯虚类: #ifndef Q4DAPPLICATION#define Q4DAP ...

  2. Java核心技术-高级特性(2)- SoftReference, WeakReference and PhantomReference

    Java.lang.ref 是 Java 类库中比较特殊的一个包,它提供了与 Java 垃圾回收器密切相关的引用类.这些引用类对象可以指向其它对象,但它们不同于一般的引用,因为它们的存在并不防碍 Ja ...

  3. delphi 对抗任务管理器关闭(提升进程到Debug模式,然后设置进程信息SE_PROC_INFO)

    [delphi] view plain copy program Project1; uses Windows; {$R *.res} function MakeMeCritical(Yes: Boo ...

  4. Extjs4.2 Desktop 拖动黑色和白色的桌面图标的解决方案

    最近做了一个extjs4.2的desktop桌面demo,该desktop从原来的包中剥离出来,并实现了桌面图标休息,拖动桌面图标,但是,用户抱怨拖动桌面图标会出现黑色和白色,测试,在 extjs4. ...

  5. HTML5初步——新的表单元素和属性

    HTML5初步--新的表单元素和属性 HTML5初步--新的表单元素和属性 <!DOCTYPE html> <html> <head> <meta chars ...

  6. HBase经常使用操作之namespace

    1.介绍 在HBase中,namespace命名空间指对一组表的逻辑分组,类似RDBMS中的database,方便对表在业务上划分.Apache HBase从0.98.0, 0.95.2两个版本号開始 ...

  7. TopCoder SRM 625 Incrementing Sequence 题解

    本题就是给出一个数k和一个数组,包含N个元素,通过每次添加�数组中的一个数的操作,最后须要得到1 - N的一个序列,不用排序. 能够从暴力法入手,然后优化. 这里利用hash表进行优化,终于得到时间效 ...

  8. linux LNMP自动安装脚本

    #!/bin/bashsoft_dir="/home/soft"config_dir="/home/config"httpd="httpd-2.0.5 ...

  9. OSPF理论总结

    OSPF学习总结一.OSPF协议的报文类型: 1. Hello 报文:主要用来发现.建立和维护邻居关系. 2. DD报文:数据库的描述报文,主要用来两台路由器的数据库同步. 3. LSR报文:链路状态 ...

  10. Spark SQL 初步

    已经Spark Submit 2013哪里有介绍Spark SQL.就在很多人都介绍Catalyst查询优化框架.经过一年的发展后,.今年Spark Submit 2014在.Databricks放弃 ...