用队列实现栈

105 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

一、题目描述:

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

  1. push 方法向队尾添加一个元素
  2. pop 删除队首的元素
  3. peek 返回队首元素
  4. empty 判断队列是否为空

二、思路分析:

这到题考察的你数据结构的功底,首先你必须了解什么是栈跟队列。

栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,这一端称为栈顶。咖啡厅内的一摞盘子是现实世界中常见的栈的例子。只能从最上面取盘子,盘子洗净后,也只能摞在这一摞盘子的最上面。栈被称为一种后入先出(LIFO,last-in-first-out)的数据结构。

图片

由于栈具有后入先出的特点,所以任何不在栈顶的元素都无法访问。为了得到栈底的元素,必须先拿掉上面的元素。对栈的两种主要操作是将一个元素压入栈和将一个元素弹出栈。

// 实现一个栈
function Stack() {
  this.dataStore = [];
}

function push(element) {
  this.dataStore.push(element)
}

function pop() {
  return this.dataStore.pop()
}

数组专门提供了push()和pop()方法,以便实现类似栈的行为。

队列是一种列表,不同的是队列只能在队尾插入元素,在队首删除元素。队列用于存储按顺序排列的数据,先进先出,这点和栈不一样,在栈中,最后入栈的元素反而被优先处理。可以将队列想象成在银行前排队的人群,排在最前面的人第一个办理业务,新来的人只能在后面排队,直到轮到他们为止。队列是一种先进先出(First-In-First-Out,FIFO)的数据结构

图片

// 实现一个队列
function Queue() {
  this.dataStore = [];
}

function push(element) {
  this.dataStore.push(element)
}

function pop() {
  return this.dataStore.shift()
}

结合使用shift()和push()方法,可以像使用队列一样使用数组。

现在已经知道了什么是栈,什么是队列,那么根据题目用栈实现队列,感觉还是没思路,不知道怎么写,我们先分析一下题目的思路:

  1. 栈有push和pop方法,往栈顶添加元素和往栈顶移除元素。
  2. 队列是往队尾添加元素,往队首移除元素,主要区别是首尾关系了。
  3. 把队列的元素全部反过来就相当于移除队尾元素了。
// 用 pop 模拟 shift 操作
let arr = [1, 2, 3]
let arr2 = []
while (arr.length) {
  arr2.push(arr.pop())
}
console.log(arr2.pop()) // 删除队首元素1

三、AC 代码:

var MyQueue = function() {
    this.inStack = [];
    this.outStack = [];
};

MyQueue.prototype.push = function(x) {
    this.inStack.push(x);
};

MyQueue.prototype.pop = function() {
    if (!this.outStack.length) {
        this.in2out();
    }
    return this.outStack.pop();
};

MyQueue.prototype.peek = function() {
    if (!this.outStack.length) {
        this.in2out();
    }
    return this.outStack[this.outStack.length - 1];
};

MyQueue.prototype.empty = function() {
    return this.outStack.length === 0 && this.inStack.length === 0;
};

MyQueue.prototype.in2out = function() {
    while (this.inStack.length) {
        this.outStack.push(this.inStack.pop());
    }
}

四、总结:

我们学会了栈转换队列的逻辑,那么我们就可以轻松的理解如何将队列转换为栈。

// 栈 push 添加, pop 删除

class MyStack {
  constructor () {
    this.queue1 = []
    this.queue2 = []
  }
  push (x) {
    this.queue2.push(x)
    while (this.queue1.length) {
      this.queue2.push(this.queue1.shift())
    }
    let temp = this.queue1
    this.queue1 = this.queue2
    this.queue2 = temp
  }
  pop () {
    return this.queue1.shift()
  }
}

const stack = new MyStack()
stack.push(88)
stack.push(99)
console.log(stack.pop())