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/

幾乎同樣的思路,每次插入的時候看看棧頂的元素,若是比插入的元素小就再插入一個棧頂的元素, 若是插入的元素更小的話,就插入這個新的元素

相關文章
相關標籤/搜索