返回
利用JavaScript妙手回春:用栈构建队列,搞定剑指 Offer JavaScript刷题第 1 天挑战!
前端
2024-01-04 22:56:01
站在剑指 Offer JavaScript刷题的起跑线上,我们面临的第一道难题便是用两个栈实现队列。栈和队列都是计算机科学中常见的数据结构,栈遵循先进后出的原则,而队列遵循先进先出的原则。乍一看,栈似乎与队列格格不入,但通过巧妙的设计,我们可以用两个栈模拟出一个队列。
栈与队列的数据结构
1. 栈
栈是一种遵循先进后出(LIFO)原则的数据结构,类似于生活中的一叠盘子。当我们把盘子叠起来时,最后放上的盘子会先被取走,这就是先进后出的原则。在栈中,我们可以通过push()方法添加元素,通过pop()方法移除元素,同时也可以通过peek()方法查看栈顶元素。
2. 队列
队列是一种遵循先进先出(FIFO)原则的数据结构,就像生活中排队等候一样。队列中的第一个元素会先被处理,这就是先进先出的原则。在队列中,我们可以通过enqueue()方法添加元素,通过dequeue()方法移除元素,同时也可以通过peek()方法查看队列头元素。
用两个栈实现队列
既然栈是先进后出,队列是先进先出,那么如何用两个栈模拟出一个队列呢?秘诀在于巧妙地利用栈的特性。
- 入队操作 :当我们需要将一个元素入队时,我们先将其压入栈A。
- 出队操作 :当我们需要将一个元素出队时,我们先将栈A中的所有元素依次压入栈B,然后将栈B中的栈顶元素弹出,这就是出队的元素。
通过这种方法,我们可以用两个栈模拟出一个队列,并且队列的基本操作enqueue()、dequeue()和peek()的时间复杂度都是O(1)。
代码实现
class Queue {
constructor() {
this.stackA = [];
this.stackB = [];
}
enqueue(element) {
this.stackA.push(element);
}
dequeue() {
if (this.stackB.length === 0) {
while (this.stackA.length > 0) {
this.stackB.push(this.stackA.pop());
}
}
return this.stackB.pop();
}
peek() {
if (this.stackB.length === 0) {
while (this.stackA.length > 0) {
this.stackB.push(this.stackA.pop());
}
}
return this.stackB[this.stackB.length - 1];
}
}
结语
通过用两个栈实现队列的挑战,我们不仅加深了对栈和队列数据结构的理解,也领略了算法设计中的巧思。剑指 Offer JavaScript刷题之旅才刚刚开始,在接下来的日子里,我们将继续探索更多精彩的算法和数据结构,不断磨炼我们的编程技能。