代码随想录二刷-栈和队列章节
232:用栈实现队列
链接: Leetcode232.用栈实现队列
类似题目: 代码随想录二刷-用队列实现栈
题目需求
- 仅使用两个栈实现先入先出队列。
- 队列应当支持一般队列支持的所有操作(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 操作是合法的。
思路
-
分析题干
a. 首先,题目说明用两个栈模拟队列。已知队列是先进先出结构,与栈的先进后出结构有差异。【第一步】
b. 所以,对于队列来说,栈底元素才是第一个要出栈的。而栈底元素要出栈,上面元素必须先全部出栈。【第二步】
c. 那上面元素不能丢啊,后面还要用到。所以就需要有个容器把它存起来,用什么存呢?这时候题干的两个栈解答了我们的疑惑。我们将第二个栈命名为临时存储栈【第三步】
d. 好的,那还有个问题。当栈底元素弹出后,那些存在临时存储栈的元素要重新压回原栈中吗?【第四步】
e. 不用,因为现在临时存储栈元素的出栈顺序,和队列要出队的顺序一致了!【第五步】
f. 那如果临时存储栈有元素,而且原栈也有新元素进来,会不会在MyQueue类实现pop的时候,原栈又有元素转移到临时存储栈,那不就破坏了出栈顺序?【第六步】
g. 这么想混淆了概念,因为现在MyQueue类要进行pop的时候,要弹出的元素在临时存储栈的栈顶,而不在原栈的栈底。因此不存在第六步的问题。【第七步】 -
写题顺序
a. 创建出两个栈
b. 先写push和empty函数
c. 再写pop函数
d. 最后写peek函数 -
注意事项
a. 注意MyQueue类的empty要判断两个栈都为空的时候才为空
b. peek可以调用已写好的pop函数 -
代码
class MyQueue {
private:
stack<int> stdIn;
stack<int> stdOut;
public:
MyQueue() {
;
}
void push(int x) {
stdIn.push(x);
}
int pop() {
if(stdOut.empty()){
while(!stdIn.empty()){
stdOut.push(stdIn.top());
stdIn.pop();
}
if(!stdOut.empty()){
int res = stdOut.top();
stdOut.pop();
return res;
}
else return -1;
}
else{
int res = stdOut.top();
stdOut.pop();
return res;
}
}
int peek() {
int res = pop();
stdOut.push(res);
return res;
}
bool empty() {
return stdIn.empty() && stdOut.empty();
}
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
参考: 代码随想录-232.用栈实现队列