队列
队列是遵循先进先出的有序集合,在队列尾部添加新元素,队列首部移除元素,最新添加的元素加在队列尾部
Queue
// 对象模拟
class Queue {
item = {}
count = 0
lastIndex = 0
enqueue(value) {
this.item[this.count] = value
this.count++
}
dequeue() {
if (this.isEmpty()) {
return undefined
}
const result = this.item[this.lastIndex]
delete this.item[this.lastIndex]
this.lastIndex++
return result
}
size() {
return this.count - this.lastIndex
}
isEmpty() {
return this.lastIndex === this.count
}
print() {
let str = this.item[0]
for (let i = 1; i < this.count; i++) {
str = `${str}=>${this.item[i]}`
}
return str
}
clear() {
this.item = {}
this.count = 0
this.lastIndex = 0
}
}
// 数组模拟
class Queue {
item = []
enqueue(value) {
this.item.push(value)
}
dequeue() {
return this.item.shift()
}
size() {
return this.item.length
}
isEmpty() {
return this.item.length === 0
}
print() {
return this.item.join('=>')
}
clear() {
this.item = []
}
}
双端队列
class DoubleQueue {
item = {}
count = 0
lastIndex = 0
// 需要判断头索引是否为0
addFront(value) {
if (this.isEmpty()) {
this.addBack()
}
if (this.lastIndex === 0) {
for (let i = this.count; i > 0; i--) {
this.item[i] = this.item[i - 1]
}
this.item[0] = value
this.count++
} else {
this.lastIndex--
this.item[this.lastIndex] = value
}
}
addBack(value) {
this.item[this.count] = value
this.count++
}
removeBack() {
if (this.isEmpty()) {
return undefined
}
this.count--
const result = this.item[this.count]
delete this.item[this.count]
return result
}
removeFront() {
if (this.isEmpty()) {
return undefined
}
const result = this.item[this.lastIndex]
delete this.item[this.lastIndex]
this.lastIndex++
return result
}
peekFront() {
return this.item[this.lastIndex]
}
peekBack() {
return this.item[this.count - 1]
}
size() {
return this.count - this.lastIndex
}
isEmpty() {
return this.lastIndex === this.count
}
print() {
let str = this.item[0]
for (let i = 1; i < this.count; i++) {
str = `${str}=>${this.item[i]}`
}
return str
}
clear() {
this.item = {}
this.count = 0
this.lastIndex = 0
}
}
示例
循环队-击鼓传花问题
0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。
例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。
输入: n = 5, m = 3 输出: 3
// 用数组
const fn = (arr: string[], dep: number) => {
const weedOutList = []
const queque = new DoubleQueue()
while (arr.length > 1) {
for (let i = 0; i < dep; i++) {
arr.push(arr.shift())
}
weedOutList.push(arr.shift())
}
return {
winnner: arr,
weedOutList,
}
}
// 用循环队列
const fn = (arr: string[], dep: number) => {
const weedOutList = []
const queque = new DoubleQueue()
for (let i = 0; i < arr.length; i++) {
queque.addBack(arr[i])
}
while (queque.size() > 1) {
for (let i = 0; i < dep; i++) {
// 出栈入栈
queque.addBack(queque.removeFront())
}
const res = queque.removeFront()
console.log(res)
weedOutList.push(res)
}
return {
winnner: queque.item,
weedOutList,
}
}
回文检查器
回文是正反都能读通的单词、词组、数或一系列字符的序列,例如 madam或 racecar。
const fn = (str: string = '') => {
if (!str) {
return false
}
let isEqual = true
const queque = new DoubleQueue()
for (let i = 0; i < str.length; i++) {
queque.addBack(str.charCodeAt(i))
}
while ((queque.size() > 1) & isEqual) {
const first = queque.removeFront()
const last = queque.removeBack()
if (first !== last) {
isEqual = false
}
}
return isEqual
}