题目描述:
/*
* 输入 :
* 给一个数组[1, 3, 1, 3, 5, 3, 2, 1],
* 给一个滑动窗口k=3,求每个窗口最大值,最后求返回所有的值里最大的数组
*
* 输出:[3,3,5,5,5,3]
*
* */
源码:
//测试用例
let arr = [1, 3, -1, -3, 5, 3, 2, 1]
// arr = [5, 5, 5, 5, 5]
arr = [5, 5, 5, 5, 5, 5, 5]
let k = 3 //滑动窗口
//滑动求出第3个元素中最大的元素最终队列是【3,3,5,5,5,3】
let kArr = []
let resultArr = [3, 3, 5, 5, 5, 3]
resultArr = []
//思路 :单调队列,维护一个pop列队 ,push队列,把大值getMax放到resultArr
//插入一个元素
function enqueue2(arr, value) { //入滑窗
//把元素前面小的值移除// arr = [-1, -3, 5]
let back = arr[arr.length - 1];
while (back !== undefined && (back < value)) {
arr.pop()
back = arr[arr.length - 1]
}
arr.push(value)
console.log('移除前面小元素之后:popMini>>', arr)
return arr
}
function getMax() {
return kArr[0] ? kArr[0] : null;
}
if (arr.length >= k) {
for (let i = 0; i < k; i++) {
if (arr[i] === undefined) continue
kArr = enqueue2(kArr, arr[i])
}
resultArr.push(getMax())
}
for (let i = k; i < arr.length; i++) {
console.log('当前进入元素》》', arr[i])
console.log('当前滑窗的列队: kArr =', kArr)
if (kArr.length >= k) {
let a = kArr.shift()
console.log('超滑窗长度,移除', a) //超滑窗时,移除
}
kArr = enqueue2(kArr, arr[i]) //把前面小移出,反最大放第一个
console.log('kArr>>', kArr)
console.log('准备加入最大值 >>', getMax())
resultArr.push(getMax())
}
console.log(resultArr)
运行:
滑窗k=3
示例1:
输入队列:
[1, 3, -1, -3, 5, 3, 2, 1]
输出:
[ 5, 5, 5, 5, 5 ]
示例2:
输入队列:
[ 5,5,5, 5, 5, 5, 5 ]
输出:
[ 5, 5, 5, 5, 5 ]
示例2:
输入队列:
[ 5,3 ]
输出:
[ ]
我这上面实现当滑动窗口时候,队列出栈判断:在入栈之前,移除对象方法是通过判断长度是否等于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];
}
}