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].数据结构

思考

  • 每次插入一个元素,若是比当前最大的元素更大,就能够更新队列里头的所有元素,由于只要它还没出去,窗口里头的最大值就是它
  • 每次拿掉一个元素,就从数组的最前面拿掉
  • 求最大值,也是从最前面拿出来

举例来讲,题目中的例子this

一开始:prototype

[1] [3,3] [3,3,-1] 最大值3code

接下来:队列

[3,-1,-3] 最大值3 [5,5,5] 最大值5 [5,5,3] 最大值5 [6,6,6] 最大值6 [7,7,7] 最大值7leetcode

最大值最小值的问题常常都是这么玩,可是要构建合适的数据结构仍是有点难度的, 纯用堆的话由于没有办法直接进行按位置访问,因此直接使用了数组get

复杂度

O(n*k)it

其实还ok。。。问题是k有可能很大io

代码

* @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/

几乎同样的思路,每次插入的时候看看栈顶的元素,若是比插入的元素小就再插入一个栈顶的元素, 若是插入的元素更小的话,就插入这个新的元素

相关文章
相关标签/搜索