栈和队列相关面试题(1)
2016-06-14 13:35
316 查看
1、实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
思路:
1、用两个栈实现,一个栈保存所有的入栈元素,另一个栈专门用来保存要返回的最小值
2、用一个栈实现,每次当插入的值大于要返回的最小值时,先把要入栈的元素入栈,再把要返回的最小值入栈,但是感觉这样会
破坏栈的结构
2、使用两个栈实现一个队列
思路:当两个栈都为空时,只能做入队操作,当两个栈不都为空时,入队、出队操作都可以实现。
inSta只用于入栈,outSta只用于出栈
过程:
入队:不管outSta是否为空,都直接把元素入栈到inSta
出队:1、当inSta、outSta都为空时,队列里面无元素,无法实现出栈
2、当outSta为空时,把inSta除栈底元素外的所有元素出栈,并按照出栈顺序入栈到outSta,把inSta的栈底元素出栈
3、当outSta不为空时,说明上一操作为出栈,此时把outSta的栈顶元素出栈即可
3、使用两个队列实现一个栈
思路:在操作完成后,元素始终只存在于一个队列中,不会存在两个队列中都有元素的情况
过程:
1、入栈:
1、两个队都为空,默认入队到que1
2、把元素入队到不为空的那个队列中
2、出栈:
1、两个对都为空,栈中无元素,无法出栈
2、把不为空的那个队列的除队尾元素全部出队,并按照出队顺序入队到另一个队列,最后再把队尾元素出队即可完成
StackAndQueue.h
test.cpp
思路:
1、用两个栈实现,一个栈保存所有的入栈元素,另一个栈专门用来保存要返回的最小值
2、用一个栈实现,每次当插入的值大于要返回的最小值时,先把要入栈的元素入栈,再把要返回的最小值入栈,但是感觉这样会
破坏栈的结构
2、使用两个栈实现一个队列
思路:当两个栈都为空时,只能做入队操作,当两个栈不都为空时,入队、出队操作都可以实现。
inSta只用于入栈,outSta只用于出栈
过程:
入队:不管outSta是否为空,都直接把元素入栈到inSta
出队:1、当inSta、outSta都为空时,队列里面无元素,无法实现出栈
2、当outSta为空时,把inSta除栈底元素外的所有元素出栈,并按照出栈顺序入栈到outSta,把inSta的栈底元素出栈
3、当outSta不为空时,说明上一操作为出栈,此时把outSta的栈顶元素出栈即可
3、使用两个队列实现一个栈
思路:在操作完成后,元素始终只存在于一个队列中,不会存在两个队列中都有元素的情况
过程:
1、入栈:
1、两个队都为空,默认入队到que1
2、把元素入队到不为空的那个队列中
2、出栈:
1、两个对都为空,栈中无元素,无法出栈
2、把不为空的那个队列的除队尾元素全部出队,并按照出队顺序入队到另一个队列,最后再把队尾元素出队即可完成
StackAndQueue.h
<strong><span style="font-size:18px;">#pragma once #include <iostream> #include <assert.h> using namespace std; #include <stack> #include <queue> template<class T> class TwoStack { public: void Push(const T& data) { if (MinDataStack.empty()==true || MinDataStack.top() > data) { MinDataStack.push(data); DataStack.push(data); } else { DataStack.push(data); } } void Pop() { assert(!DataStack.empty()); if (MinDataStack.top() == DataStack.top()) { MinDataStack.pop(); DataStack.pop(); } else { DataStack.pop(); } } T& MinData() { assert(!DataStack.empty()); return MinDataStack.top(); } T& Top() { assert(!DataStack.empty()); return DataStack.top(); } bool Empty() { return DataStack.empty(); } size_t Size() { return DataStack.size(); } private: stack<T> DataStack; stack<T> MinDataStack; }; template<class T> class TwoStackForQueue { public: void Push(const T& data) { InStack.push(data); } void Pop() { assert(InStack.empty() == false || OutStack.empty() == false);//如果全为空,那么则是空队列,不进行操作 while (InStack.empty() == false) { OutStack.push(InStack.top()); InStack.pop(); } OutStack.pop(); } T& Front() { assert(InStack.empty() == false || OutStack.empty() == false);//如果全为空,那么则是空队列,不进行操作 while (InStack.empty() == false) { OutStack.push(InStack.top()); InStack.pop(); } return OutStack.top(); } T& Back() { assert(InStack.empty() == false || OutStack.empty() == false);//如果全为空,那么则是空队列,不进行操作 while(OutStack.empty() == false) { InStack.push(OutStack.top()); OutStack.pop(); } return InStack.top(); } bool Empty() { return (InStack.empty() == true && OutStack.empty() == true); } size_t Size() { return InStack.size()+OutStack.size(); } //友元函数 template<typename T> friend ostream& operator<<(ostream& os, const TwoStackForQueue<T>& queue); private: stack<T> InStack; stack<T> OutStack; }; //输出运算符重载 template<class T> ostream& operator<<(ostream& os,const TwoStackForQueue<T>& queue) { TwoStackForQueue<T> coutqueue(queue); while(coutqueue.OutStack.size() > 0) { os<<coutqueue.OutStack.top()<<" "; coutqueue.OutStack.pop(); } while (coutqueue.InStack.size() > 0) { coutqueue.OutStack.push(coutqueue.InStack.top()); coutqueue.InStack.pop(); } while(coutqueue.OutStack.size() > 0) { os<<coutqueue.OutStack.top()<<" "; coutqueue.OutStack.pop(); } return os; } template<class T> class TwoQueueForStack { public: void Push(const T& data) { //每次push数据,总能保证一个队列为空 if (_Queue2.empty() == true) { _Queue1.push(data); } else//_Queue1.empty() == true { _Queue2.push(data); } } void pop() { assert(_Queue1.empty() == false || _Queue2.empty() == false); if (_Queue1.empty() == false) { while (_Queue1.front() != _Queue1.back()) { _Queue2.push(_Queue1.front()); _Queue1.pop(); } _Queue1.pop(); } else//_Queue2.empty() == false { while (_Queue2.front() != _Queue2.back()) { _Queue1.push(_Queue2.front()); _Queue2.pop(); } _Queue2.pop(); } } T& Top() { assert(_Queue1.empty() == false || _Queue2.empty() == false); if (_Queue1.empty() == false) { return _Queue1.back(); } else { return _Queue2.back(); } } bool Empty() { return _Queue1.empty() == true && _Queue2.empty() == true; } size_t Size() { return _Queue1.size()+_Queue2.size(); } //template<typename T> //friend ostream& operator<<(ostream& os,const TwoQueueForStack<T>& stack); private: queue<T> _Queue1; queue<T> _Queue2; }; //template<class T> //ostream& operator<<(ostream& os,const TwoQueueForStack<T>& stack) //{ // TwoQueueForStack<T> countstack(stack); // // while (countstack._Queue1.size() > 0) // { // cout<<countstack._Queue1.front()<<" "; // countstack._Queue1.pop(); // } // // while (countstack._Queue2.size() > 0) // { // count<<countstack._Queue2.front()<<" "; // countstack._Queue2.pop(); // } // // while (countstack._Queue1.size() > 0) // { // cout<<countstack._Queue1.front()<<" "; // countstack._Queue1.pop(); // } // return os; //} </span></strong>
test.cpp
<strong><span style="font-size:18px;">#define _CRT_SECURE_NO_WARNINGS 1 #include "StackAndQueue.h" void Test1() { //实现一个栈,要求实现Push(出栈)、Pop(入栈)、 //Min(返回最小值的操作)的时间复杂度为O(1) //思路:有两个栈,每次压栈进入DataStack之前,先与MinDataStack的栈顶元素进行 //比较,如果比MinDataStack的栈顶元素小,那么数据即进入DataStack栈中也进入MinDataStack中 TwoStack<int> twostack; twostack.Push(1); twostack.Push(5); twostack.Push(9); twostack.Push(3); twostack.Push(2); twostack.Push(0); twostack.Push(6); cout<<twostack.MinData()<<endl; cout<<twostack.Top()<<endl; cout<<twostack.Size()<<endl; cout<<twostack.Empty()<<endl; twostack.Pop(); twostack.Pop(); twostack.Pop(); cout<<twostack.MinData()<<endl; cout<<twostack.Top()<<endl; cout<<twostack.Size()<<endl; cout<<twostack.Empty()<<endl; } void Test2() { //使用两个栈实现一个队列 //思路:有两个栈,一个在InStack栈上只操作入栈,一个OutStack栈上只操作出栈 TwoStackForQueue<int> queue; queue.Push(1); queue.Push(2); queue.Push(3); queue.Push(4); queue.Push(5); queue.Push(6); cout<<queue<<endl; queue.Pop(); queue.Pop(); cout<<queue<<endl; cout<<queue.Front()<<endl; cout<<queue.Back()<<endl; cout<<queue.Empty()<<endl; cout<<queue.Size()<<endl; } void Test3() { //使用两个队列实现一个栈 TwoQueueForStack<int> stack; stack.Push(6); stack.Push(8); stack.Push(0); stack.Push(5); stack.Push(9); stack.Push(1); stack.pop(); stack.pop(); stack.pop(); stack.pop(); stack.pop(); cout<<stack.Top()<<endl; cout<<stack.Size()<<endl; cout<<stack.Empty()<<endl; } int main() { //Test1(); //Test2(); //Test3(); system("pause"); return 0; } </span></strong>
相关文章推荐
- 面试题9:递归和非递归
- 面试题22 栈的压入、弹出序列
- Java程序员也应该知道的系统知识系列之(网卡,cpu,内存,硬盘,虚拟化)
- 编程之法:面试和算法心得
- 要准备了:JAVA面试题及答案汇总
- 腾讯面试全程
- 面试腾讯全过程
- 程序员,应该掌握的英语词汇
- 面试题21 包含Min函数的栈
- 非技术相关的面试技巧(文章内容来自他人博客)
- 升级您的ERP系统
- 写给嵌入式程序员的循环冗余校验(CRC)算法入门引导
- Android面试题(文章内容来自他人博客)
- 与WWDC大会同步,黑马程序员iOS4.0课程震撼出炉
- Java笔试面试题整理第八波
- 面试题47-2:不使用新的变量,交换两个变量的值
- 面试题47:不用加减乘除做加法
- 程序员面试50题(1)—查找最小的k个元素[算法]
- 运维面试题和答案
- 求职前夕的不眠夜