Sliding Window Maximum
2015-08-10 14:57
274 查看
题目
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].
思考
每次插入一个元素,如果比当前最大的元素更大,就可以更新队列里头的全部元素,因为只要它还没出去,窗口里头的最大值就是它每次拿掉一个元素,就从数组的最前面拿掉
求最大值,也是从最前面拿出来
举例来说,题目中的例子
一开始:
[1]
[3,3]
[3,3,-1] 最大值3
接下来:
[3,-1,-3] 最大值3
[5,5,5] 最大值5
[5,5,3] 最大值5
[6,6,6] 最大值6
[7,7,7] 最大值7
最大值最小值的问题经常都是这么玩,但是要构建合适的数据结构还是有点难度的,
纯用堆的话因为没有办法直接进行按位置访问,所以直接使用了数组
复杂度
O(n*k)其实还ok。。。问题是k有可能很大
代码
```js/**@param {number[]} nums
@param {number} k
@return {number[]}
*/
var maxSlidingWindow = function(nums, k) {
if (nums.length === 0) {
return [];
}
var ret = [];
var h = new Queue();
for(var i = 0; i<k; i++) {
h.enq(nums[i]);
}
for(; i < nums.length; i++) {
ret.push(h.peek());
h.deq();
h.enq(nums[i]);
}
ret.push(h.peek());
return ret;
};
function Queue() {
this._q = [];
}
Queue.prototype.enq = function(ele) {
var size = this._q.push(ele);
var i = size - 2;
while(i >= 0) {
if (this._q[i] <= this._q[i+1]) {
this._q[i] = this._q[i+1];
} else {
break;
}
i--;
}
}
Queue.prototype.peek = function() {
if (this._q.length === 0 ) {
throw new Error('queue is empty');
}
return this._q[0];
}
Queue.prototype.deq = function(){
return this._q.shift();
}
console.log(maxSlidingWindow([1,3,-1,-3,5,3,6,7],3));
console.log(maxSlidingWindow([1],1));
console.log(maxSlidingWindow([1, -1],1));
console.log(maxSlidingWindow([-7,-8,7,5,7,1,6,0], 4));
console.log(maxSlidingWindow([1,-9,8,-6,6,4,0,5], 4));
# 类似的问题 https://leetcode.com/problems/min-stack/ 几乎一样的思路,每次插入的时候看看栈顶的元素,如果比插入的元素小就再插入一个栈顶的元素, 如果插入的元素更小的话,就插入这个新的元素
相关文章推荐
- 线段树之 HDU4578Transformation
- Android onTouch事件与手势操作
- hdu 1558
- jQuery 判断所有图片加载完成
- Codevs2370 小机房的树
- UIPasteboard Example – Read, Write and Share data between apps
- JS中Cookie详解及示例展示
- 内存分配方式
- 一个服务接口的多个实现的选择
- LCS 最大子段和,最大子段和在原数组的首末地址
- 【ecos】service
- hdu 3338 网络流填数字
- Java双缓冲技术
- apache tomcat集群
- 排列、组合相关知识
- 线段树(二)区间更新
- 静态代码块,构造代码块和构造函数的区别
- 中文分词与停用词的作用
- Java开发web的几种开发模式
- Retrofit 介绍