题目描述
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(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
思想
利用两个栈 stIn 和 stOut 来模拟一个队列的行为。队列是一种先入先出(FIFO)的数据结构,但栈是后入先出(LIFO)的数据结构。这里的目标是使用栈的属性来实现一个队列的操作。下面是每个方法的详细解释:
MyQueue()
MyQueue() {}
这是一个简单的构造函数,它没有执行任何操作。这个构造函数的存在是为了初始化 MyQueue 对象。stIn 和 stOut 作为栈会自动被初始化。
push(int x)
void push(int x) { // 入队
stIn.push(x);
}
功能:将一个元素 x 加入队列。
实现:直接将元素推入 stIn 栈。由于栈是 LIFO 的,所以新加入的元素总是位于 stIn 的顶部。这个操作对应队列的入队(enqueue)操作。
pop()
int pop() { // 出队
if (stOut.empty()) {
while (!stIn.empty()) {
stOut.push(stIn.top());
stIn.pop();
}
}
int result = stOut.top();
stOut.pop();
return result;
}
功能:从队列中移除队首元素,并返回它。
实现:
步骤1:首先检查 stOut 是否为空。如果为空,那么将 stIn 中的所有元素逆序倒入 stOut 中。这样,stIn 的底部元素(即最早加入的元素)会转移到 stOut 的顶部,从而符合队列的出队顺序。
步骤2:从 stOut 弹出并返回栈顶元素,这个元素是当前队列的队首元素。
peek()
int peek() { // 查看队首元素
int res = this->pop();
stOut.push(res);
return res;
}
功能:返回队列的队首元素,但不移除它。
实现:
步骤1:使用 pop 方法获取队首元素。
步骤2:将获取到的元素再次压回 stOut 栈,以保持队列状态不变。
empty()
bool empty() {
return stIn.empty() && stOut.empty();
}
功能:检查队列是否为空。
实现:只有当两个栈 stIn 和 stOut 都为空时,队列才真正为空。这是因为队列的所有元素要么在 stIn 中,要么在通过倒置后在 stOut 中。
完整代码
#include<iostream>
#include<stack>
using namespace std;
class MyQueue {
public:
stack<int> stIn, stOut;
MyQueue() {}
void push(int x) { // 入队
stIn.push(x);
}
int pop() { //出队
if(stOut.empty()){
while(!stIn.empty()){
stOut.push(stIn.top());
stIn.pop();
}
}
int result = stOut.top();
stOut.pop();
return result;
}
int peek() { //
int res = this->pop();
stOut.push(res);
return res;
}
bool empty() {
return stIn.empty() && stOut.empty();
}
};
int main() {
MyQueue queue;
queue.push(1);
queue.push(2);
cout << "Peek: " << queue.peek() << endl; // 应输出 1
cout << "Pop: " << queue.pop() << endl; // 应输出 1
cout << "Empty: " << (queue.empty() ? "true" : "false") << endl; // 应输出 false
return 0;
}