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 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:
- How about using a data structure such as deque (double-ended queue)?
- The queue size need not be the same as the window’s size.
- 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天,我打算再请两周假,这样整个十二月份基本都能有时间好好做题和学习。 抽空要把加拿大签证办了,然后过去签美国签证,这样明年二月就可以顺利回国和顺便去趟日本玩了。
二刷:
这回也是使用一刷的方法,但是顺了很多。 也有更快速的方法,两次遍历输入入组,留给下一次再刷时来解决。
- 首先我们读完题目,确定是用sliding window的方法来做
- 我们需要先去除一些invalid case,并且判断出结果数组res的长度是 len - k + 1,这里len是输入数组的长度
- 然后我们建立一个doubly linked list叫做window,用来保存滑动窗口中出现的数组最大值的index,注意这里存的是index而不是value
- 现在我们可以开始遍历数组
- 首先,我们要查看window头部index,假如超过了 i - k,我们要从前部poll出这个index
- 接下来我们对比window尾部index位置上的值 和 当前nums[i],假如nums[i]更大,则我们poll出window的尾部index,再继续进行比较,直到window为空或者nums[i] < nums[window.peelLast()], 保证window中是一个递减排列
- 我们将i加入到window中
- 查看是否 i - (k - 1) >= 0,假如满足这个条件,则表示我们已经判断了至少k个元素,可以生成结果。
- 最后返回结果。 要注意写的过程中各种边界,真正面试过程中跑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的更多相关文章
- 【LeetCode】239. Sliding Window Maximum
Sliding Window Maximum Given an array nums, there is a sliding window of size k which is moving fr ...
- 【刷题-LeetCode】239. Sliding Window Maximum
Sliding Window Maximum Given an array nums, there is a sliding window of size k which is moving from ...
- 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 ...
- (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 ...
- [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 ...
- [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 ...
- 【LeetCode】239. Sliding Window Maximum 解题报告(Python&C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 单调递减队列 MultiSet 日期 题目地址:ht ...
- leetcode 239 Sliding Window Maximum
这题是典型的堆排序算法,只是比一般的堆算法多了删除的操作,有两件事需要做: 1 用一个hash表存储从输入数组索引到堆数组(用于实现堆的那个数组)所以的映射,以便在需要删除一个元素的时候能迅速定位到堆 ...
- 239 Sliding Window Maximum 滑动窗口最大值
给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口 k 内的数字.滑动窗口每次只向右移动一位.例如,给定 nums = [1,3,-1,-3, ...
随机推荐
- C# CacheHepler Class
internal class CacheHelper { /// <summary> /// Insert value into the cache using /// appropria ...
- objdump的使用方法和 symbol table的每列的含义
一.objdump的用法 objdump命令的man手册 objdump [-a] [-b bfname| --target=bfdname] [-C] [--debugging] ...
- Java读取本地文件进行unicode解码
工具使用: package test.opservice; import eh.util.MapValueUtil; import java.io.BufferedReader; import jav ...
- Android手机做无线中继路由器
为什么要拿手机做路由器?因为我现在每天要带着一个火柴盒大小的路由器(703n).它提供了一个f了q的无线网络,电脑,手机,平板等设备连接上这个无线网络之后之后就可以自由上twitter,看youtub ...
- Win8.1 IIS6 SQL SERVER 2012 执行 SqlServices.InstallSessionState 出错
新装了WIN8.1,感觉很不错. 新建了第一个站点是,在执行 SqlServices.InstallSessionState("localhost", null, SessionS ...
- VirtualBox虚拟机安装MSDOS和MINIX2.0.0双系统
1. 在VirtualBox中新建一个MSDOS虚拟机. 2.下载一个MSDOS软盘镜像. 3.启动虚拟机,提示选择安装盘时,选择步骤2下载过来的MSDOS镜像. 4.正常启动进入DOS命令行,用FD ...
- 初见IOS的UI之:UI控件的属性frame bounds center 和transform
这些属性,内部都是结构体:CGRect CGPoint CGFloat 背景知识:所有的控件都是view的子类,屏幕就是一个大的view:每个view都有个viewController,它是view的 ...
- Flex:在PANEL的title上加一个button[转]
//转自:http://www.cnblogs.com/GFantasy/archive/2010/03/05/1678917.htmlpackage{ import mx.containers.Pa ...
- FMS (端口问题)如何穿透防火墙
转自http://www.cnblogs.com/zhchongyao/archive/2010/01/22/1653803.html 先是管理端口,就是fms2_console文件连接到server ...
- 使用Forms进行身份验证(Asp.net)
1.背景 以往项目登陆后的用户信息都是存放在session中,但session有一个问题就是读取的时候需要先实例化所在类,在调用对象()如果用static修饰,则可能到时多次登陆sessio ...