题目
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
思路
简单题。
就是要用两个栈来模拟,一个输入栈一个输出栈,找好逻辑关系即可。
注意一下 peek和empty函数的简洁写法。
可以看出peek()的实现,直接复用了pop()。
class MyQueue {
public:
stack<int> stIn; //输入栈
stack<int> stOut; //输出栈
MyQueue() {
}
void push(int x) {
stIn.push(x);
}
int pop() {
//输出栈为空,则将输入栈全部压入
if(stOut.empty()){
while(!stIn.empty()){
stOut.push(stIn.top());
stIn.pop();
}
}
//非空,则直接弹出
auto result =stOut.top();
stOut.pop();
return result;
}
int peek() {
if(stOut.empty()){
while(!stIn.empty()){
stOut.push(stIn.top());
stIn.pop();
}
}
//非空,则直接返回开头
return stOut.top();
//有没有发现上面代码跟pop很像...所以可以这么写
int res = this->pop(); // 直接使用已有的pop函数
stOut.push(res); // 因为pop函数弹出了元素res,所以再添加回去
return res;
}
bool empty() {
if(stIn.empty() && stOut.empty()){
return true;
}else{
return false;
}
//简洁写法
return stIn.empty() && stOut.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();
*/
教训
很明显,我就犯了这样一个错误:
在工业级别代码开发中,最忌讳的就是 实现一个类似的函数,直接把代码粘过来改一改就完事了。样的项目代码会越来越乱,一定要懂得复用,功能相近的函数要抽象出来,不要大量的复制粘贴,很容易出问题!(踩过坑的人自然懂)