题目:

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 disable Passwords must meet complexity requirements[windows 7]

    The Password complexity is a Local Policy setting named "Passwords must meet complexity require ...

  2. apache ab的安装步骤

    1:到apache官方网站http://httpd.apache.org/download.cgi#apache24下载最新版本的apache,然后解压,执行如下命令: ./configure –pr ...

  3. 用python实现两个文本合并

    一段时间前在网上看到一段面试题,要求如下: employee文件中记录了工号和姓名 cat employee.txt: 100 Jason Smith 200 John Doe 300 Sanjay ...

  4. Golang学习笔记

    一.基础 1. Hello World程序 demo: package main import "fmt" // 注释 //注释 func main() { fmt.Printf( ...

  5. javascript 柯里化

    先看一下代码 function add(){ var sum=0; for(var i=0;i<arguments.length;i++){ sum+=arguments[i]; } retur ...

  6. 表达式语言之java对正则表达式的处理

    正则表达式用于字符串匹配,字符串查找,字符串替换等.例如注册email格式的验证等.java中处理正则表达式相关的类主要有java.lang.String,java.util.regex.Patter ...

  7. Jquer Ajax xmlhttp请求成功了,为什么一直在error函数里面

    转载自http://www.cnblogs.com/sky_Great/archive/2013/01/18/2866861.html 并进行整理: 今天遇到了一个极其奇怪的问题,用各种工具检查都能看 ...

  8. hive 操作(转)

    1.命令行操作 (1)打印查询头,需要显示设置: set hive.cli.print.header=true; (2)加"--",其后的都被认为是注释,但 CLI 不解析注释.带 ...

  9. 快书包CEO徐智明反思:我犯下哪些错误

    新浪科技 刘璨 1月23日,快书包CEO徐智明在微博上公开“叫卖”快书包,在业内引起不小反响.这家创立于2010年要做“网上711”的创业公司,曾以独特的“一小时送达”服务在业内成为关注焦点. “如果 ...

  10. 在云服务器搭建WordPress博客(五)创建和管理文章分类

    不同主题的文章划分到不同的分类,有助于访客寻找他们想要的内容,提高用户体验.所以,为你的网站创建文章分类是很有必要的.那么,WordPress系统如何创建和管理文章分类呢?今天倡萌就简单介绍一下. 创 ...