题目

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false

思路

简单题。
就是要用两个栈来模拟,一个输入栈一个输出栈,找好逻辑关系即可。
注意一下 peek和empty函数的简洁写法。
可以看出peek()的实现,直接复用了pop()。

  1. class MyQueue {
  2. public:
  3. stack<int> stIn; //输入栈
  4. stack<int> stOut; //输出栈
  5. MyQueue() {
  6. }
  7. void push(int x) {
  8. stIn.push(x);
  9. }
  10. int pop() {
  11. //输出栈为空,则将输入栈全部压入
  12. if(stOut.empty()){
  13. while(!stIn.empty()){
  14. stOut.push(stIn.top());
  15. stIn.pop();
  16. }
  17. }
  18. //非空,则直接弹出
  19. auto result =stOut.top();
  20. stOut.pop();
  21. return result;
  22. }
  23. int peek() {
  24. if(stOut.empty()){
  25. while(!stIn.empty()){
  26. stOut.push(stIn.top());
  27. stIn.pop();
  28. }
  29. }
  30. //非空,则直接返回开头
  31. return stOut.top();
  32. //有没有发现上面代码跟pop很像...所以可以这么写
  33. int res = this->pop(); // 直接使用已有的pop函数
  34. stOut.push(res); // 因为pop函数弹出了元素res,所以再添加回去
  35. return res;
  36. }
  37. bool empty() {
  38. if(stIn.empty() && stOut.empty()){
  39. return true;
  40. }else{
  41. return false;
  42. }
  43. //简洁写法
  44. return stIn.empty() && stOut.empty();
  45. }
  46. };
  47. /**
  48. * Your MyQueue object will be instantiated and called as such:
  49. * MyQueue* obj = new MyQueue();
  50. * obj->push(x);
  51. * int param_2 = obj->pop();
  52. * int param_3 = obj->peek();
  53. * bool param_4 = obj->empty();
  54. */

教训

很明显,我就犯了这样一个错误:
在工业级别代码开发中,最忌讳的就是 实现一个类似的函数,直接把代码粘过来改一改就完事了。样的项目代码会越来越乱,一定要懂得复用,功能相近的函数要抽象出来,不要大量的复制粘贴,很容易出问题!(踩过坑的人自然懂)