栈和队列面试题1【菜鸟学习日记】
来源:互联网 发布:mac有必要分区吗 编辑:程序博客网 时间:2024/06/06 08:38
开篇点题,今天做了几道栈和队列的题,
在此,记录分享
1、实现一个栈,要求这个栈实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作的时间复杂度为O(1))
来分析一下,
思路1:我们可以底层用两个栈来实现
先建个类,写个框架,实现3个接口
class MinSt{public: void Push(const int& x) {...} void Pop() {...} int Min() {...}protected: stack<int> _st; stack<int> _minst;};
然后我们再来分析一下如何写,分析一下过程
虽然我们底层是用两个栈实现的,但外面看起来要像一个栈,那么我们这两个栈要保持一致,同进同出
这里进栈出栈时,_st栈不用特殊考虑,但_minst我们是用它记录最小值的所以要特殊考虑
我们可以从上图看到,_minst入栈的要求是比当前栈顶的数小或者等于才能入栈,否则将当前栈顶再入栈
void Push(const int& x) { _st.push(x); if (_minst.size() == 0||x<_minst.top()) { _minst.push(x); } else { _minst.push(_minst.top()); } }
此时我们_minst的栈顶永远是最小值
出栈时,只要考虑不为空即可
void Pop() { if (!_st.empty() && !_minst.empty()) { _st.pop(); _minst.pop(); } }
返回最小值就Pop出_minst栈顶
int Min() { if (!_minst.empty()) { return _minst.top(); } }
测试一下
void test1(){ MinSt s; s.Push(5); s.Push(3); s.Push(6); s.Push(1); s.Push(2); s.Pop(); s.Pop(); cout << s.Min() << endl;}
这个写法还可以优化,_minst中重复入栈3,我们还可以用其他方法优化,后面再补充
2、用两个栈实现一个队列
我们先来画图分析一下
class TwoStackOneQueue{public: ...private: stack<int> PushStack; stack<int> PopStack;};
先创建两个栈,一个用来入,一个用来出
我们大概先说一下思路
入栈1,2,3
当要Pop时,将1,2,3导入进PopStack,这时的栈顶,就是我们应该要Pop的正确数了
然后我们再入栈时应该入PushStack
首先我们先来实现Push()接口,这个接口我们不用特别考虑什么,想清楚入栈都入PushStack
void Push(const int&x) { //入时永远入PushStack栈 PushStack.push(x); }
然后就是出栈
我们每次出PopStack即可,如果为空了,就将PushStack倒过去,再出就好
下面是全部代码
class TwoStackOneQueue{public: void Push(const int&x) { //入时永远入PushStack栈 PushStack.push(x); } void Pop() { if (PopStack.empty()) { PutPop(); } PopStack.pop(); } int& Front() { if (PopStack.empty()) { PutPop(); } return PopStack.top(); } bool Empty() { return PushStack.empty() && PopStack.empty(); } size_t Size() { return PushStack.size() + PopStack.size(); }private: void PutPop() { while (!PushStack.empty()) { PopStack.push(PushStack.top()); PushStack.pop(); } }private: stack<int> PushStack; stack<int> PopStack;};void test2(){ TwoStackOneQueue q; q.Push(1); q.Push(2); q.Push(3); q.Pop(); cout<<q.Front()<<endl;//2 q.Pop(); cout << q.Front() << endl;//3 q.Push(4); q.Pop(); cout << q.Front() << endl;//4}
3、用两个队列实现一个栈
入队列1,2,3,4
可是我们现在要出4,所以我们可以将1,2,3全放到另一个队列中去,就可以出4了
我们如数据的时候都入不为空有数据的那个,这样我们才能就一个在出的时候将前面数据移过去,出队列
要知道哪个空队列,写个函数就好了
还有就是移数据也可以单独写个函数,方便后面调用,并最好都设为私有,外面看不到,这样只能看到那些栈有的接口,更好一些
private: void PutEmpty() { QEmpty(); while (nonemptyq->size() > 1) { emptyq->push(nonemptyq->front()); nonemptyq->pop(); } } void QEmpty() { if (_q2.empty()) { swap(emptyq, nonemptyq); } }
其它的也就没什么了,不说了,上全部代码
class TwoQueueOneStack{public: void Push(const int&x) { //入时入非空的队列 QEmpty(); nonemptyq->push(x); } void Pop() { PutEmpty(); nonemptyq->pop(); } int& Top() { QEmpty(); return nonemptyq->back(); } bool Empty() { return _q1.empty() && _q2.empty(); } size_t Size() { return _q1.size() + _q2.size(); }private: void PutEmpty()//移数据 { QEmpty(); while (nonemptyq->size() > 1) { emptyq->push(nonemptyq->front()); nonemptyq->pop(); } } void QEmpty() { if (_q2.empty()) { swap(emptyq, nonemptyq); } }private: queue<int> _q1; queue<int> _q2; queue<int>* emptyq = &_q1; queue<int>* nonemptyq = &_q2;};void test3(){ TwoQueueOneStack s; s.Push(1); s.Push(2); s.Push(3); s.Push(4); s.Pop(); cout << s.Top()<<endl;//3 s.Push(5); cout << s.Top() << endl;//5}
以上,今天总结完毕,剩下的以后再写吧!
———-【菜鸟日记】by 小宣子
阅读全文
0 0
- 栈和队列面试题1【菜鸟学习日记】
- 栈和队列面试题
- 栈和队列面试题
- 栈和队列面试题
- 【面试题】栈和队列的面试题
- 顺序表与链表的面试题【菜鸟学习日记】
- 栈和队列相关面试题(1)
- 栈和队列相关面试题(1)
- 栈和队列面试题总结
- 【面试题七】栈和队列
- 栈和队列面试题(一)
- 栈和队列面试题(二)
- 栈和队列面试题(三)
- 栈和队列面试题(四)
- 栈和队列常见面试题
- 栈和队列 相关 面试题
- 栈和队列相关面试题2
- 队列和栈的面试题
- Linux——nfs
- 基础类
- RPC和WebService的比较
- qrcode a样式,url情况,引导页,二维码
- 蓝桥杯 矩形面积交
- 栈和队列面试题1【菜鸟学习日记】
- 简单的彩色图像分割
- Lesson 3 上机练习题——继承
- linux命令service xxx start是如何工作的
- 1139. First Contact (30)
- 网络Cisco实验-跨交换机相同VLAN通信
- ps--浮生掠影
- RTMP协议详解
- iOS开发UI篇—Quartz2D使用(把图片绘制到Bitmap上>输出图片)