//对象模拟队列
class Queue {
constructor() {
this.items = {}
this.num = 0; //表示队列长度
this.lowestNum = 0; //用于表示队列头
}
enqueue(element) { //向队列尾部添加元素
this.items[this.num] = element;
this.num++
}
dequeue() { //移除第一项元素并返回
if (this.isEmpty()) {
return undefined
}
const result = this.items[this.lowestNum];
delete this.items[this.lowestNum];
this.lowestNum++
return result;
}
peek() { //返回队头元素
if (this.isEmpty()) {
return undefined
}
return this.items[this.lowestNum]
}
isEmpty() { //判断是否为空
return this.num - this.lowestNum === 0;
}
size() { //返回队列元素个数
return this.num - this.lowestNum;
}
clear() { //清空队列
this.items = {}
this.num = 0;
this.lowestNum = 0;
}
toString() { //字符串化
if (this.isEmpty()) {
return ''
}
let objString = `${this.items[this.lowestNum]}`
for (let i = this.lowestNum + 1; i < this.num; i++) {
objString = `${objString},${this.items[i]}`
}
return objString
}
}
//对象模拟双端队列:允许在队列两端添加和移除元素
class Deque {
constructor() {
this.items = {};
this.num = 0; //表示队列长度
this.lowestNum = 0; //用于表示队列头
}
addFront(element) { //向队列头部添加元素
if (this.isEmpty()) { //如果队列为空,直接添加元素
this.addBack(element);
} else if (this.lowestNum > 0) { //如果lowestNum大于0,说明,队头元素被删除过
this.lowestNum--;
this.items[this.lowestNum] = element;
} else { //lowestNum等于0
for (let i = this.num; i > 0; i--) {
this.items[i] = this.items[i - 1];
}
this.num++;
this.items[this.lowestNum] = element;
}
}
addBack(element) { //向队列尾部添加元素
this.items[this.num] = element;
this.num++;
}
removeFront() { //移除第一项元素并返回
if (this.isEmpty()) {
return undefined;
}
let result = this.items[this.lowestNum];
delete this.items[this.lowestNum];
this.lowestNum++;
return result;
}
removeBack() { //移除后端第一项元素并返回
if (this.isEmpty()) {
return undefined;
}
this.num--;
let result = this.items[this.num];
delete this.items[this.num];
return result;
}
peekFront() { //返回队头元素
if (this.isEmpty()) {
return undefined;
}
return this.items[this.lowestNum];
}
peekBack() { //返回队尾元素
if (this.isEmpty()) {
return undefined;
}
return this.items[this.num-1];
}
clear() { //清空队列
this.items = {};
this.num = 0;
this.lowestNum = 0;
}
size() { //返回队列长度
return this.num - this.lowestNum;
}
isEmpty() { //判断队列是否为空
return this.num - this.lowestNum === 0;
}
toString() { //字符串化
if (this.isEmpty()) {
return '';
}
let objString = `${this.items[this.lowestNum]}`;
for (let i = this.lowestNum + 1; i < this.num; i++) {
objString = `${objString},${this.items[i]}`;
}
return objString;
}
}
队列相关算法
1.用队列实现栈(力扣225)
var MyStack = function () {
this.queue = [];
this.queue_clone = [];
};
MyStack.prototype.push = function (x) {
this.queue.push(x)
};
MyStack.prototype.pop = function () {
if (this.queue.length === 0) {
return undefined
}
let len = this.queue.length;
for (let i = 0; i < len - 1; i++) {
this.queue_clone.push(this.queue.shift())
}
let result = this.queue.shift();
this.queue = this.queue_clone;
this.queue_clone = [];
return result;
};
MyStack.prototype.top = function () {
return this.queue[this.queue.length - 1];
};
MyStack.prototype.empty = function () {
return this.queue.length === 0;
};
2.用栈实现队列(力扣232)
var MyQueue = function () {
this.stack = [];
this.stack_clone = [];
};
MyQueue.prototype.push = function (x) {
this.stack.push(x);
};
MyQueue.prototype.pop = function () {
if (this.stack.length === 0) {
return undefined;
}
let len = this.stack.length;
for (let i = len - 1; i > 0; i--) {
this.stack_clone.push(this.stack.pop())
}
let result = this.stack.pop();
let len2 = this.stack_clone.length;
for (let i = len2 - 1; i > -1; i--) {
this.stack.push(this.stack_clone.pop())
}
return result;
};
MyQueue.prototype.peek = function () {
if (this.stack.length === 0) {
return undefined;
}
return this.stack[0];
};
MyQueue.prototype.empty = function () {
return this.stack.length === 0;
};
3.滑动窗口的平均值(剑指041)
var MovingAverage = function (size) {
this.queue = [];
this.num = size;
this.sum = 0;
};
MovingAverage.prototype.next = function (val) {
if (this.queue.length < this.num) {
this.queue.push(val);
} else {
this.queue.shift();
this.queue.push(val);
}
this.queue.forEach(val => {
this.sum += val;
})
let result = this.sum / this.queue.length
this.sum = 0;
return result;
};
4.最近的请求次数(力扣933)
var RecentCounter = function () {
this.queue = [];
this.num = 0;
};
RecentCounter.prototype.ping = function (t) {
this.queue.push(t);
for (let i = 0; i < this.queue.length; i++) {
if ((this.queue[i] >= t - 3000) && (this.queue[i] <= t)) {
this.num++
}
}
let result = this.num;
this.num = 0;
return result;
};
5.队列的最大值(剑指059—middle)
var MaxQueue = function () {
this.queue = [];
};
MaxQueue.prototype.max_value = function () {
if (this.queue.length === 0) {
return -1
}
let max = 0;
for (let i = 0; i < this.queue.length; i++) {
max = Math.max(max, this.queue[i])
}
return max
};
MaxQueue.prototype.push_back = function (value) {
this.queue.push(value);
};
MaxQueue.prototype.pop_front = function () {
if (this.queue.length === 0) {
return -1
}
return this.queue.shift()
};
其它
循环队列——击鼓传花
function hotPotato(playersList, num) {
const queue = new Queue();
const losersList = [];
for (let i = 0; i < playersList.length; i++) {
queue.enqueue(playersList[i])
}
while (queue.size() > 1) {
for (let i = 0; i < num; i++) {
queue.enqueue(queue.dequeue())
}
losersList.push(queue.dequeue())
}
return {
winner: queue.dequeue(),
loser: losersList
}
}
双端队列——验证回文串
function palindromeChecker(string) {
if (string === undefined || string === null || (string !== null && string.length === 0)) {
return false;
}
let string1 = string.toLowerCase().split(' ').join('');
let deque = new Deque();
let isEqual = true;
let firstChar, lastChar;
for (let i = 0; i < string1.length; i++) {
deque.addBack(string1[i])
}
while (deque.size() > 1 && isEqual) {
firstChar = deque.removeFront();
lastChar = deque.removeBack();
if (firstChar !== lastChar) {
isEqual = false;
}
}
return isEqual
}