[路飞]化栈为队

124 阅读2分钟

题目描述

实现一个MyQueue类,该类用两个栈来实现一个队列。

分析

输出:一个实例,具有题目要求的方法,且符合要求

解题思路

本质上看,本题要求我们用两个去实现一个队列。我们先来看他们的区别:

栈是先入后出,队列是先入先出,这是他们的区别,如果顺序一样的话用一个数组不就得了。。。

对于栈:我们用数组来实现,根据要求,只用他的 pushpop 方法
对于队列:我们用两个栈(popStack, pushStack)来模拟,最难的地方在于怎么去找到对尾的元素,也就是 poppeek 的元素。

我们接下来挨个去实现所需方法:

push: 直接调用 this.pushStack.push

pop:
这是本题的难点,首先我们明确一点,popStack 只用于 pop 元素,只要涉及到找队列头部的元素,就要 popStack.pop()
OK,那接下来问题就简单了,如果现在 popStack 里边没有元素,我就要从 pushStack 里找,我要的是 pushStack开头的那个元素,所谓我们可以这么干,不断的从 pushStackpop,没拿到一个元素就 pushpopStack 里,所以现在 popStack 里最后一个元素,就是 pushStack 开头的那个了~。
紧接着我们执行 popStack.pop(),返回元素即可

peek:
跟上面一样,只不过不要删除,只要返回值之前再 push 回去就行了

empty:
检查两个栈是否为空,都为空则队列为空,否则不是

代码

/**
 * Initialize your data structure here.
 */
var MyQueue = function () {
  this.popStack = []
  this.pushStack = []
}

/**
 * Push element x to the back of queue.
 * @param {number} x
 * @return {void}
 */
MyQueue.prototype.push = function (x) {
  this.pushStack.push(x)
}

/**
 * Removes the element from in front of queue and returns that element.
 * @return {number}
 */
MyQueue.prototype.pop = function () {
  if (!this.popStack.length) {
    while (this.pushStack.length) {
      this.popStack.push(this.pushStack.pop())
    }
  }

  console.log(this.popStack.toString())
  return this.popStack.pop()
}

/**
 * Get the front element.
 * @return {number}
 */
MyQueue.prototype.peek = function () {
  if (!this.popStack.length) {
    while (this.pushStack.length) {
      this.popStack.push(this.pushStack.pop())
    }
  }

  const ret = this.popStack.pop()
  this.popStack.push(ret)
  return ret
}

/**
 * Returns whether the queue is empty.
 * @return {boolean}
 */
MyQueue.prototype.empty = function () {
  return !this.pushStack.length && !this.popStack.length
}

复杂度

时间:O(N), pop, peek 最坏需要遍历到所有元素
空间:O(N), 需要两个栈来存所有的数据