剑指 Offer 09. 用两个栈实现队列

64 阅读1分钟

题目

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

 

示例 1:

输入:
["CQueue","appendTail","deleteHead","deleteHead","deleteHead"]
[[],[3],[],[],[]]
输出: [null,null,3,-1,-1]

示例 2:

输入:
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[[],[],[5],[2],[],[]]
输出: [null,-1,null,null,5,2]

提示:

  • 1 <= values <= 10000
  • 最多会对 appendTail、deleteHead 进行 10000 次调用

题解

stackA用于队列保存入队的元素,栈stackB用于队列出队的元素。

执行appendTail方法时,把元素放入stackA;

执行deleteHead方法时,首先检查stackB出队栈中是否有元素,有元素直接调用stackB.pop()让队列元素出队。否则依次把stackA中的元素压入到stackB中,此时stackA 栈顶的元素就变成了stackB的栈顶元素,正好符合队列先进先出的要求,然后执行stackB.pop(), 返回队首元素。如果出队元素不存在,返回-1即可。

这题的关键在于想到用两个栈,一个做入队栈,一个做出队栈,出队时将入队栈元素依次压入出队栈,正好实现了元素顺序的反转,满足队列先进先出的要求。

代码

var CQueue = function() {
    this.stackA = [];
    this.stackB = [];
};

/** 
 * @param {number} value
 * @return {void}
 */
CQueue.prototype.appendTail = function(value) {
    this.stackA.push(value);
};

/**
 * @return {number}
 */
CQueue.prototype.deleteHead = function() {
    const lenB = this.stackB.length;
    if (lenB === 0) {
        while(this.stackA.length) {
            this.stackB.push(this.stackA.pop());
        }
    }
    return this.stackB.pop() || -1;
};

/**
 * Your CQueue object will be instantiated and called as such:
 * var obj = new CQueue()
 * obj.appendTail(value)
 * var param_2 = obj.deleteHead()
 */

原题链接

剑指 Offer 09. 用两个栈实现队列