持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情
前言
继续学习栈与队列的相关知识,并进行刷题。今天刷了一道困难题,确实难度要高很多,在这发表一下我对这道题的理解。
题目
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回 滑动窗口中的最大值 。
示例
初始思路
这道题最明显的解题办法就是暴力解决,但是暴力解决的复杂度十分高。像滑动窗口这种先入先出的结构就是明显的队列的结构。
我们会想到使用队列在队列里排序然后返回队列里最大的值,但是排序后的队列并不能像从前一样保持出队列的顺序。由此,我们需要一个队列可以push入元素,可以pop出元素,也可以返回我们一段内的最大值。
解题方法
pop(value):如果窗口pop出的元素等于单调队列的出口元素,队列弹出元素。否则不进行弹出。
push(value):如果push的元素大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止。
front:返回队首元素。
代码
var maxSlidingWindow = function (nums, k) {
class MonoQueue {
queue;
constructor() {
this.queue = [];
}
enqueue(value) {
let back = this.queue[this.queue.length - 1];
while (back !== undefined && back < value) {
this.queue.pop();
back = this.queue[this.queue.length - 1];
}
this.queue.push(value);
}
dequeue(value) {
let front = this.front();
if (front === value) {
this.queue.shift();
}
}
front() {
return this.queue[0];
}
}
let helperQueue = new MonoQueue();
let i = 0,
j = 0;
let resArr = [];
while (j < k) {
helperQueue.enqueue(nums[j++]);
}
resArr.push(helperQueue.front());
while (j < nums.length) {
helperQueue.enqueue(nums[j]);
helperQueue.dequeue(nums[i]);
resArr.push(helperQueue.front());
i++, j++;
}
return resArr;
};
后记
今天这道题对我目前来说已经吃力,希望二刷的时候可以从容不迫。