请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
说明:
你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
示例 1:
输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]
解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
要点:栈是后进先出,队列是先进先出。
解题思路:
创建两个栈,一个栈st2用来存储入队元素,另一个栈st1用来存储翻转过后的元素(翻转后元素顺序就是队列的顺序了),当st1为空时,再把st2的元素出栈并入栈st1(这时st2中的元素在st1中就翻转了)。因为队列的队头元素如果不出队就不会变,所以可以等st1空了再把st1@2翻转入栈st1。判断队列空时,也就是判断st1和st2是否同时为空。
代码实现
// 无注释版
class MyQueue {
private:
stack<int>st1;
stack<int>st2;
void inst2() {
while(!st2.empty()) {
st1.push(st2.top());
st2.pop();
}
}
public:
MyQueue() {
}
void push(int x) {
st2.push(x);
}
int pop() {
if(st1.empty()) {
inst2();
}
int result=st1.top();
st1.pop();
return result;
}
int peek() {
if(st1.empty()) {
inst2();
}
return st1.top();
}
bool empty() {
return st1.empty()&&
st2.empty();
}
};
// 注释版
class MyQueue { // 类实现
private:
// 创建栈st1存储翻转后的元素,
// st2存储入队元素
stack<int>st1;
stack<int>st2;
// 把st2中元素出栈并入栈到st1的函数
void inst2() {
while(!st2.empty()) {
st1.push(st2.top());
st2.pop();
}
}
public:
MyQueue() {
}
void push(int x) { //入队则直接入栈st2
st2.push(x);
}
int pop() { // 如果st1为空,把st2中元素
if(st1.empty()) { // 翻转到st1
inst2();
}
//返回队头元素并出队
int result=st1.top();
st1.pop();
return result;
}
// 返回队头元素
int peek() {
if(st1.empty()) {
inst2();
}
return st1.top();
}
// 判断队列是否为空
bool empty() {
return st1.empty()&&
st2.empty();
}
};