题目:

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. How to understand ReferenceGroup control on Form[AX2012]

    在AX2012的Form开发中,微软引入了新的控件ReferenceGroup,它用在Lookup其他表RecId的时候显示更人性化的字段,它的使用还必须从表的索引说起.AX2012的表有这些索引(h ...

  2. MySQL数据库主从复制

    一.MySQ主从复制(主库写入数据,从库读取数据) MySql官方下载地址:http://dev.mysql.com/downloads/mysql/ MySql常用命令: 设置密码 UPDATE U ...

  3. WPF样式——多条件触发器

    希望创建多个条件都为真时才激发的触发器,就需要使用MultiTrigger提供的Condition集合 <Window x:Class="Styles.MultiTrigger&quo ...

  4. MySQL主从修复

    MySQL主从故障修复 测试库:192.168.1.2 主192.168.1.3 从 192.168.1.4 主 4又是2的从库192.168.1.5 从 有人修改了192.168.1.2和192.1 ...

  5. XCODE快捷键和功能汇总篇(不断更新)

    快捷键 command+b(build) 编译 command+r(run) 运行编译后程序鼠标放在代码元素上,按command然后单击,可以看到元素的属性

  6. 【转】jquery-取消冒泡

    转自:http://blog.163.com/css_mm/blog/static/209182176201262665157634/ 1.通过返回false来取消默认的行为并阻止事件起泡. jQue ...

  7. map中的erase成员函数用法

    转载于 http://www.cnblogs.com/graphics/archive/2010/07/05/1771110.html  http://hi.baidu.com/sdkinger/it ...

  8. Introduction to Deep Neural Networks

    Introduction to Deep Neural Networks Neural networks are a set of algorithms, modeled loosely after ...

  9. NS记录

    NS(Name Server)记录是域名服务器记录,用来指定该域名由哪个DNS服务器来进行解析. 1名词简介 您注册域名时,总有默认的DNS服务器,每个注册的域名都是由一个DNS域名服务器来进行解析的 ...

  10. JS内存管理测试

    打开调试器,切换到timer,点击左下角的record按钮开始,切换到memory视图,在文档中点击鼠标左右键,看股价走势图 function Allocate(kbs){ this.mem = ne ...