定义队列
Queue.ts
interface IQueue<T> {
enqueue(element: T): void;
dequeue(): T | undefined;
peek(): T | undefined;
isEmpty(): boolean;
size(): number;
}
class ArrayQueue<T> implements IQueue<T> {
private queue: T[];
constructor() {
this.queue = [];
}
enqueue(element: T): void {
this.queue.push(element);
}
dequeue(): T | undefined {
return this.queue.shift();
}
peek(): T | undefined {
return this.queue[0];
}
isEmpty(): boolean {
return this.queue.length === 0;
}
size(): number {
return this.queue.length;
}
}
export { ArrayQueue };
应用
击鼓传花
HotPotato.ts
import { ArrayQueue } from "./Queue";
// 击鼓传花,到固定次数手上拿着花的淘汰,最后剩下的人是胜者。
function HotPotato(names: string[], num: number) {
if (names.length === 0) return;
const queue = new ArrayQueue<string>();
// 将所有name入队
for (const name of names) {
queue.enqueue(name);
}
while (queue.size() > 1) {
for (let i = 1; i < num; i++) {
// 非数字对应的人先出队再入队
let name = queue.dequeue();
if (name) {
queue.enqueue(name);
}
}
// 删除次数对应的人
queue.dequeue();
}
return queue.dequeue();
}
const leftNames = ["aaa", "bbb", "ccc", "ddd", "eee", "fff", "jjj"];
const num = 3;
console.log(HotPotato(leftNames, num));
约瑟夫环
LastRemaining.ts
import { ArrayQueue } from "./Queue";
// 约瑟夫环 逻辑同击鼓传花一样
function LastRemaining(n: number, m: number) {
const queue = new ArrayQueue<number>();
for (let i = 0; i < n; i++) {
queue.enqueue(i);
}
while (queue.size() > 1) {
for (let i = 1; i < m; i++) {
// 以下注释代码有问题 因为当num为0时 if(num) 判断时为false
// let num = queue.dequeue()!;
// if (num) {
// console.log(num);
// queue.enqueue(num);
// }
queue.enqueue(queue.dequeue()!);
}
queue.dequeue();
}
return queue.dequeue()!;
}
console.log(LastRemaining(5, 3));