队列的特点是先入先出,出入元素是在不同的两端(队头和队尾),而栈的特点是先入后出,出入元素都是在同一端(栈顶)。
下图就是一个典型的队列的结构。需要加入队列中的元素是往队尾添加的,而需要出队的元素从队头出。
在栈中有一个指针Top,永远指向栈顶元素,如果栈为空,那么Top就为nil。在栈结构中无论是入栈还是出栈,都是操作栈顶元素。所以入栈顺序与出栈顺序是相反的。
既然我们拥有两个队列,那么我们可以让其中一个栈作为队列的入口,负责插入新元素;另一个栈作为队列的出口,负责移除老元素。
原理说明
由于栈只能操作一端,因此我们peek或者pop的时候也只去操作栈顶元素,要达到目的我们需要在push的时候将队头的元素放到栈顶即可。具体做法是先将栈依次pop并push至另一个辅助栈中,最后将新的元素push到辅助栈顶,然后再将辅助栈中的元素依次pop放回原栈中。
比如我们现在栈中已经是1,2,3,4了。我们现在要push一个5.
push之前是这样的:
然后我们将栈中的元素转移到辅助栈,最后将新的元素添加到栈顶。
然后再将辅助栈中的元素依次pop放回原栈中。
整个过程是这样的:
image出队的时候,显然只要对stack执行pop操作即可
/*
* @lc app=leetcode id=232 lang=javascript
*
* [232] Implement Queue using Stacks
*/
/**
* Initialize your data structure here.
*/
var MyQueue = function() {
// tag: queue stack array
this.stack = [];
this.helperStack = [];
};
/**
* Push element x to the back of queue.
* @param {number} x
* @return {void}
*/
MyQueue.prototype.push = function(x) {
let cur = null;
while ((cur = this.stack.pop())) {
this.helperStack.push(cur);
}
this.helperStack.push(x);
while ((cur = this.helperStack.pop())) {
this.stack.push(cur);
}
};
/**
* Removes the element from in front of queue and returns that element.
* @return {number}
*/
MyQueue.prototype.pop = function() {
return this.stack.pop();
};
/**
* Get the front element.
* @return {number}
*/
MyQueue.prototype.peek = function() {
return this.stack[this.stack.length - 1];
};
/**
* Returns whether the queue is empty.
* @return {boolean}
*/
MyQueue.prototype.empty = function() {
return this.stack.length === 0;
};
/**
* Your MyQueue object will be instantiated and called as such:
* var obj = new MyQueue()
* obj.push(x)
* var param_2 = obj.pop()
* var param_3 = obj.peek()
* var param_4 = obj.empty()
*/
网友评论