一、题目简述
原先的个人思路:
用两个栈,一个作为主操作栈,另一个作为临时操作栈,push全在主操作栈进行.pop就需要临时借用一下tmp栈,全倒在临时操作栈中,然后在临时操作栈中pop,然后再全部倒回主操作栈即可.判断空,则直接看主栈是否为空即可
class MyQueue { public: MyQueue() {} void push(int x) { stack_one.push(x); } int pop() { while(!stack_one.empty()) { tmp.push(stack_one.top()); stack_one.pop(); }//完成倒序 int pos=tmp.top(); tmp.pop(); while(!tmp.empty()) { stack_one.push(tmp.top()); tmp.pop(); } return pos; } int peek() { while(!stack_one.empty()) { tmp.push(stack_one.top()); stack_one.pop(); }//完成倒序 int pos=tmp.top(); while(!tmp.empty()) { stack_one.push(tmp.top()); tmp.pop(); } return pos; } bool empty() { return stack_one.empty(); } private: stack<int> stack_one;//作为主栈 stack<int> tmp; };
二、参考思路与优化
在push数据的时候,只要数据放进输入栈就好,但在pop的时候,操作就复杂一些,输出栈如果为空,就把进栈数据全部导入进来(注意是全部导入),再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。(不用每次都来回倒腾)
最后如何判断队列为空呢?如果进栈和出栈都为空的话,说明模拟的队列为空了。
拓展---pop代码的复用
peek()的实现,直接复用了pop(), 要不然,对stOut判空的逻辑又要重写一遍。
再多说一些代码开发上的习惯问题,在工业级别代码开发中,最忌讳的就是 实现一个类似的函数,直接把代码粘过来改一改就完事了。
这样的项目代码会越来越乱,一定要懂得复用,功能相近的函数要抽象出来,不要大量的复制粘贴,很容易出问题!(踩过坑的人自然懂)
工作中如果发现某一个功能自己要经常用,同事们可能也会用到,自己就花点时间把这个功能抽象成一个好用的函数或者工具类,不仅自己方便,也方面了同事们。
class MyQueue { public: stack<int> stIn; stack<int> stOut; /** Initialize your data structure here. */ MyQueue() { } /** Push element x to the back of queue. */ void push(int x) { stIn.push(x); } /** Removes the element from in front of queue and returns that element. */ int pop() { // 只有当stOut为空的时候,再从stIn里导入数据(导入stIn全部数据) if (stOut.empty()) { // 从stIn导入数据直到stIn为空 while(!stIn.empty()) { stOut.push(stIn.top()); stIn.pop(); } } int result = stOut.top(); stOut.pop(); return result; } /** Get the front element. */ int peek() { int res = this->pop(); // 直接使用已有的pop函数 stOut.push(res); // 因为pop函数弹出了元素res,所以再添加回去 return res; } bool empty() { return stIn.empty() && stOut.empty(); } };