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

题目的地址:

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.

  1. Window position Max
  2. --------------- -----
  3. [1 3 -1] -3 5 3 6 7 3
  4. 1 [3 -1 -3] 5 3 6 7 3
  5. 1 3 [-1 -3 5] 3 6 7 5
  6. 1 3 -1 [-3 5 3] 6 7 5
  7. 1 3 -1 -3 [5 3 6] 7 6
  8. 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个操作

不就是线性吗?

关键在于,一次实际的操作可能只有弹出一次,而压栈的操作被集成在某次弹出时集中执行了。

具体代码:

  1. public class Solution {
  2.  
  3. public int[] maxSlidingWindow(int[] nums, int k) {
  4. if (nums.length == 0) {
  5. return nums;
  6. }
  7. int[] res = new int[nums.length - k + 1];
  8. MinQueue queue = new MinQueue();
  9. for (int i = 0; i < k; i ++) {
  10. queue.push(nums[i]);
  11. }
  12. res[0] = queue.getMax();
  13. int index = 1;
  14. for (int i = k; i < nums.length; i ++) {
  15. queue.pop();
  16. queue.push(nums[i]);
  17. res[index ++] = queue.getMax();
  18. }
  19. return res;
  20. }
  21.  
  22. class MinQueue {
  23.  
  24. LinkedList<Integer> stack1 = new LinkedList<Integer>();
  25. LinkedList<Integer> stack2 = new LinkedList<Integer>();
  26. LinkedList<Integer> maxOne = new LinkedList<Integer>();
  27. LinkedList<Integer> maxTwo = new LinkedList<Integer>();
  28.  
  29. public void push(Integer item) {
  30. pushOne(item);
  31. }
  32.  
  33. public Integer pop() {
  34. Integer res = null;
  35. if (stack2.size() == 0) {
  36. while (stack1.size() != 0) {
  37. pushTwo(popOne());
  38. }
  39. }
  40. res = stack2.pop();
  41. maxTwo.pop();
  42. return res;
  43. }
  44.  
  45. public Integer getMax() {
  46. Integer one = maxOne.peek();
  47. Integer two = maxTwo.peek();
  48. if (one == null) {
  49. return two;
  50. } else if (two == null){
  51. return one;
  52. }
  53. return one > two ? one : two;
  54. }
  55.  
  56. private Integer popOne() {
  57. Integer res = null;
  58. maxOne.pop();
  59. res = stack1.pop();
  60. return res;
  61. }
  62.  
  63. private void pushOne(Integer item) {
  64. stack1.push(item);
  65. if (stack1.size() == 1) {
  66. maxOne.push(item);
  67. } else {
  68. Integer front = maxOne.peek();
  69. if (front < item) {
  70. maxOne.push(item);
  71. } else {
  72. maxOne.push(front);
  73. }
  74. }
  75. }
  76.  
  77. private void pushTwo(Integer item) {
  78. stack2.push(item);
  79. if (stack2.size() == 1) {
  80. maxTwo.push(item);
  81. } else {
  82. Integer front = maxTwo.peek();
  83. if (front < item) {
  84. maxTwo.push(item);
  85. } else {
  86. maxTwo.push(front);
  87. }
  88. }
  89. }
  90. }
  91.  
  92. }

【原创】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. VK Cup 2012 Qualification Round 1---C. Cd and pwd commands

    Cd and pwd commands time limit per test 3 seconds memory limit per test 256 megabytes input standard ...

  2. [to do list][PCB][questions]and[plan]

    Questions 2014/5/29 1.最后检查布板,除了用netlist查,还有没有更快的方法? 2014/6/8 1.      R的location中心究竟是哪个? watermark/2/ ...

  3. SVN的项目管理

    基于SVN的项目管理——集中与分散   我们在此处不讨论 GIT 比 SVN 好多少,也不讨论 Maven 和 Gradle 哪个好用,基于现有的开发环境,大多数公司还是采用 SVN + Maven ...

  4. 指尖上的电商---(12)SolrAdmin中加入多核的还有一种方法

    这一节中我们演示下solr中创建多核的还有一种方法. 接第10讲,首先关闭tomcatserver 1.解压solr-4.8.0后,找到solr-4.8.0以下的example目录下的multicor ...

  5. 中科燕园GIS外包----机场project地理信息系统EGIS

    对于大型机场建设project,不管project建设过程中.还是project建设完毕后.进入执行和维护阶段.必然要产生和使用到大量的各式各样的信息资料,包含project项目过程管理控制类文档,p ...

  6. poj2226(最小点覆盖)

    传送门:Muddy Fields 题意:一个由r行c列方格组成的田地,里面有若干个方格充满泥泞,其余方格都是草.要用长度不限,宽度为1的长木板来覆盖这些泥方格,但不能覆盖草地.最少要用多少个长木板. ...

  7. c#操作.mpp文件

    原文地址:http://mjm13.iteye.com/blog/532404 所需设置    在工程中增加引用Microsoft Project 11.0 Object Library,该引用在co ...

  8. zoj3329(概率dp)

    题目连接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3754 题意:有三个骰子,分别有k1,k2,k3个面. 每次掷骰子,如 ...

  9. 云计算分布式大数据神器Spark实战高手之旅

    从2012年1月份研究Spark到如今已经两年多的时间了. 在这两年多的时间里比較彻底的研究了Spark的源码并已经在2014年4月24日编写完毕了世界上第一本Spark书籍. 鉴于CSDN在大陆IT ...

  10. Max Sum (hdu 1003 简单DP水过)

    Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Su ...