题目:

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?

Hint:

    1. How about using a data structure such as deque (double-ended queue)?
    2. The queue size need not be the same as the window’s size.
    3. Remove redundant elements and the queue should store only elements that need to be considered.

链接: http://leetcode.com/problems/sliding-window-maximum/

题解:

长题目思密达。题目大意是给定一个数组和一个长为k的window,求这个window在从头到尾滑动时,每个window里的最大值组成的集合。考虑了很久,最后求助了Discuss。原理使用一个Deque,或者用doubly linkedlist也可以。我们队这个数组维护一个递减的双端队列,队列的内容为坐标index。每次移动时,移除小于当前队首坐标的元素,同时比较当前元素与队尾元素的大小,假如队尾元素较小,移除队尾元素,继续比较当前元素和队尾。比较完毕后把当前元素加入到队列中, 最后判断是否窗口已满,要输出到结果集中。

Time Complexity - O(n), Space Complexity - O(n)。

public class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums == null || nums.length == 0)
return new int[]{};
int len = nums.length;
int[] res = new int[len - k + 1];
Deque<Integer> dq = new LinkedList<>(); for(int i = 0; i < len; i++) {
while(!dq.isEmpty() && dq.peekFirst() < i - (k - 1)) // maintain a window of length k
dq.pollFirst(); while(!dq.isEmpty() && nums[dq.peekLast()] < nums[i]) // compare last elements with nums[i]
dq.pollLast(); dq.offerLast(i); if(i >= k - 1)
res[i - (k - 1)] = nums[dq.peekFirst()]; // since we have a descendent deque, first is always the largest in window
} return res;
}
}

题外话:

最近感恩节,祝福大家感恩节快乐。这几天总在网上看deal,没有好好刷题,难得的4天休假也没有完全利用起来。Cousera的斯坦福算法1总算上完了,跟得很累,每周都要花不少时间。但是有一些思想和题目比较经典,比如closest pair,find inversions,matrix multiply,还有find median in data stream等等。有时间要好好复习一下。下面记录几个link有空时学习。

https://leetcode.com/discuss/64811/easy-to-understand-double-heap-solution-in-java

http://andrew-algorithm.blogspot.com/

http://www.stefan-pochmann.info/spam/

下周上一周班,周四有公司年会,之后那周是培训5天,我打算再请两周假,这样整个十二月份基本都能有时间好好做题和学习。 抽空要把加拿大签证办了,然后过去签美国签证,这样明年二月就可以顺利回国和顺便去趟日本玩了。

二刷:

这回也是使用一刷的方法,但是顺了很多。 也有更快速的方法,两次遍历输入入组,留给下一次再刷时来解决。

  1. 首先我们读完题目,确定是用sliding window的方法来做
  2. 我们需要先去除一些invalid case,并且判断出结果数组res的长度是 len - k + 1,这里len是输入数组的长度
  3. 然后我们建立一个doubly linked list叫做window,用来保存滑动窗口中出现的数组最大值的index,注意这里存的是index而不是value
  4. 现在我们可以开始遍历数组
    1. 首先,我们要查看window头部index,假如超过了 i - k,我们要从前部poll出这个index
    2. 接下来我们对比window尾部index位置上的值 和 当前nums[i],假如nums[i]更大,则我们poll出window的尾部index,再继续进行比较,直到window为空或者nums[i] < nums[window.peelLast()], 保证window中是一个递减排列
    3. 我们将i加入到window中
    4. 查看是否 i - (k - 1) >= 0,假如满足这个条件,则表示我们已经判断了至少k个元素,可以生成结果。
  5. 最后返回结果。  要注意写的过程中各种边界,真正面试过程中跑1 ~ 2个例子就会比较清晰。

Java:

Time Complexity - O(n), Space Complexity - O(n)。

public class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums == null || nums.length < k || k <= 0) return nums;
int len = nums.length;
int[] res = new int[len - k + 1];
LinkedList<Integer> window = new LinkedList<>();
for (int i = 0; i < len; i++) {
if (!window.isEmpty() && window.peekFirst() <= i - k) window.pollFirst();
while (!window.isEmpty() && nums[window.peekLast()] < nums[i]) window.pollLast();
window.offerLast(i);
if (i - (k - 1) >= 0) res[i - (k - 1)] = nums[window.peek()];
}
return res;
}
}

Reference:

https://leetcode.com/discuss/47139/this-is-a-typical-monotonic-queue-problem

https://leetcode.com/discuss/99541/not-the-best-but-the-fastest-beat-97%25

https://leetcode.com/discuss/94516/simple-java-solution-that-beats-100%25-submissions

https://leetcode.com/discuss/83402/simple-java-solution-beats-98-87%25

https://leetcode.com/discuss/46578/java-o-n-solution-using-deque-with-explanation

https://leetcode.com/discuss/62695/o-n-solution-in-java-with-two-simple-pass-in-the-array

239. Sliding Window Maximum的更多相关文章

  1. 【LeetCode】239. Sliding Window Maximum

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

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

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

  3. 239. Sliding Window Maximum *HARD* -- 滑动窗口的最大值

    Given an array nums, there is a sliding window of size k which is moving from the very left of the a ...

  4. (heap)239. Sliding Window Maximum

    题目: Given an array nums, there is a sliding window of size k which is moving from the very left of t ...

  5. [leetcode]239. 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 ...

  6. [LeetCode] 239. 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. 【LeetCode】239. Sliding Window Maximum 解题报告(Python&C++)

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

  8. leetcode 239 Sliding Window Maximum

    这题是典型的堆排序算法,只是比一般的堆算法多了删除的操作,有两件事需要做: 1 用一个hash表存储从输入数组索引到堆数组(用于实现堆的那个数组)所以的映射,以便在需要删除一个元素的时候能迅速定位到堆 ...

  9. 239 Sliding Window Maximum 滑动窗口最大值

    给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口 k 内的数字.滑动窗口每次只向右移动一位.例如,给定 nums = [1,3,-1,-3, ...

随机推荐

  1. 无法访问Fedora的samba共享

    配置好samba服务后,却发现windows无法访问.经过多次试验与fedora的防火墙有关系. 关闭防火墙: #service iptables stop 或清空规则: #iptables -F w ...

  2. Python标准库 urllib2 的使用

    1.Proxy 的设置 urllib2 默认会使用环境变量 http_proxy 来设置 HTTP Proxy. 如果想在程序中明确控制 Proxy,而不受环境变量的影响,可以使用下面的方式 impo ...

  3. QQ群里收集的外企iOS开发的笔试题

    一组外企iOS开发的笔试题,您能回答出来吗?从群里收集来的. 1 why can't NSArray contain NSInteger Instance? with which extra step ...

  4. cocos2dx中创建动画的三种方法

    1.最最原始的方法,先创建动画帧,再创建动画打包(animation),再创建动画(animate) 第一步: 创建动画帧:CCSpriteFrame,依赖于原始的资源图片(xx.png,xx.jpg ...

  5. iOS VideoToolbox硬编H.265(HEVC)H.264(AVC):2 H264数据写入文件

    本文档为iOS VideoToolbox硬编H.265(HEVC)H.264(AVC):1 概述续篇,主要描述: CMSampleBufferRef读取实际数据 序列参数集(Sequence Para ...

  6. android studio 突然出现Gradle project sync failed 错误

    出现: 之前还是好好的,突然就出现Gradle project sync failed  错误,网上原因可能是工具的问题. 解决办法: 重新打开android studio就好了.不知道大家还有其他的 ...

  7. tomcat 优化实记

    好记性不如烂笔头,以下是 tomcat 无脑优化 1.内存设置(VM参数调优)(1). Windows环境下,是tomcat解压版(执行startup.bat启动tomcat)  解决办法:修改“%T ...

  8. 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

    // test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...

  9. 让32位Eclipse和64位Eclipse同时在64的Windows7上运行

    转自让32位Eclipse和64位Eclipse同时在64的Windows7上运行 参考这篇文章:http://wenku.baidu.com/view/57994c270066f5335a81214 ...

  10. PhotoshopCS4轻松将PSD分层导出为Png分层

    大家在网上都下载过PSD分层素材,有时候想把素材分层导出,以往做法是一层一层导出,可是这样效率太低,其实利用PS自带功能可以轻松导出PNG分层.     我们先打开一个PSD文件. 文件有7个图层,分 ...