239. 滑动窗口最大值
题解
思路1:双端队列
- 思路利用数组模拟一个双端队列,用双端队列来作为窗口,当窗口宽度不到k时,不推最大值,当窗口宽度到达k时不断维持k的宽度,每次求解最大值并推入结果中。
- 分析时间复杂度一个loop 嵌套Math.max()对k长度window的选最大值O(n * k) 空间复杂度O(k)
- 代码实现
if(k >nums.length || k <= 0 ) return []
// 在初始化的时候就把k个数推入到窗口中
let window = [...nums.slice(0,k)], res = []
// 总共num.length 个数已经推入了k个还剩 k-num.length个
for (let i = k; i <= nums.length; i++) {
res.push(Math.max(...window))
window.shift()
window.push(nums[i])
}
return res
思路2:单调队列
- 思路 利用单调队列,对nums进行遍历并手动维护一个单调递减队列,当需要被推入得值大于队尾的值时把之前小于他的都弹出。
- 分析时间复杂度O(n)空间复杂度O(k)
- 代码实现
var maxSlidingWindow = function (nums, k) {
// 边界条件
if (k > nums.length || k <= 0) return []
let deque = [], res = []
for (let i = 0; i < nums.length; i++) {
// 如果nums[i]比栈尾的数大,则弹出
while (deque.length && deque[deque.length - 1] < nums[i]) {
deque.pop()
}
// nums[i]入栈
deque.push(nums[i])
// 删除离开窗口的元素
if(deque[0] === nums[i - k]) deque.shift()
// 推入最大值
if(i >= k - 1) res.push(deque[0])
}
return res
};
思路的通过时间的对比
思路一时间
思路2二时间