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

287 阅读2分钟

题目描述

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

image.png

方法:双栈

解题思路

  1. 理清栈的特性是什么? 栈类似摞一堆书,放一本新书的时候是放在前一本书的上面,拿走一本书的时候得拿最上面的书,除此之外,没有其他办法操作书。如果要拿从上往下数的第三本,得先把上面的两本书都拿起来,才能拿第三本。术语就是先进后出(First In Last Out)。

  2. 理清队列的特性是什么? 队列更好理解,类似于排队,就像排队进地铁,肯定是先排的人先进。术语是先进先出(First In First Out)。

  3. 如何用两个栈实现队列? 既然队列的特性是先进先出,那么进入的时候,直接用一个栈(称为 inStack)压入即可,出队的时候,让栈能够实现先进入的能够先出去即可。这时候再使用一个栈(称为 outStack),我们把栈 inStack 的元素都先出栈加入 outStack,这时候 outStack 的元素再出栈就实现了队列的先进先出了。

    • 如果 outStack 不为空,直接将 outStack的元素出栈
    • 如果 outStack 为空,inStack不为空,就把 inStack 的元素全部出栈搬到 outStack,再将 outStack 的元素出栈。否则返回 -1(两个栈内都没有元素了)

代码

JavaScript

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

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

/**
 * @return {number}
 */
CQueue.prototype.deleteHead = function () {
	if (!this.outStack.length && !this.inStack.length) return -1;
	if (!this.outStack.length) {
		while (this.inStack.length) {
			this.outStack.push(this.inStack.pop());
		}
	}
	return this.outStack.pop();
};

复杂度分析

时间复杂度空间复杂度
O(1)O(n)
appendTailO(1)deleteHead 为均摊 O(1),对于每个元素,至多入栈和出栈各两次n 是操作总数

总结

维护两个栈,分别实现队列的出队和入队。

参考资料

用两个栈实现队列