思路
维护一个长度最大为 k
的数组 queen
(里面存 index),让输入数组 nums
中的元素依次进入该数组。每有新元素进入的时候,对数组进行维护:删除比该元素小的数值的索引,将当前元素的索引存入数组末尾。这样可以做到数组第一个元素永远是最大的。
例如:nums = [1,5,4,9,7,8,6]
,k=3
,数值进出 queen
的过程如下:
i = 0 queen = [0]
i = 1 queen = [1] // 5 比 1 大,删掉 1 的 index,存入 5 的 index
i = 2 queen = [1, 2] // 4 没 5 大,index 放入数组末尾,输出 5
i = 3 queen = [3] // 9 比 4 和 5 都大,删除前面的数值,将 9 的 index 存入,输出 9
i = 4 queen = [3, 4] // 7 没 9大,index 放入数组末尾,输出 9
i = 5 queen = [3, 5] // 8 比 7大,但没 9 大,移除 7 的 index,输出 9
i = 6 queen = [5, 6] // 9 的 index 已出界,需要移除;6 比 8 小,输出 8
需要注意的是:
- 当
i < k - 1
的时候是不用出最大值的 - 当
queen
里第一个元素的下标小于当前i - k
的时候,是要被移出数组的
另一种思路是维护一个大顶堆,时间复杂度是 O ( log 2 n ) O(\log_2n) O(log2n)。上面这个思路时间复杂度是 O ( n ) O(n) O(n),比维护大顶堆稍好。
代码
➥ JavaScript
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
var maxSlidingWindow = function (nums, k) {
if (!nums) {
return []
}
const res = [] // 结果数组
const queen = []
for (let i = 0; i < nums.length; i++) {
if (i > 0) {
if (i - k >= queen[0]) { // 注意点2
queen.shift()
}
while (queen.length > 0 && nums[queen[queen.length - 1]] < nums[i]) {
queen.pop()
}
}
queen.push(i)
if (i >= k - 1) { // 注意点1
res.push(nums[queen[0]])
}
}
return res
};