栈和队列常考面试题(一)
1. 实现一个栈,要求实现出栈,入栈,Min返回最小值的操作的时间复杂度为o(1)
思路:要使这些操作的时间复杂度为o(1),则必须保证栈的每个元素只被遍历一次。求解时需要借助两个栈,一个入数据,一个入所遍历过数据的最小值,遍历结束后,放最小值的栈的栈顶元素即为所求的最小值。
#include<iostream>
using namespace std;
#include<stack>
#include<assert.h>
#define capacity 10
template<class T>
class StackWithMin
{
public:
void Push(const T&value)
{
m_data.push(value);
if (m_min.size() == 0 || value < m_min.top())
m_min.push(value);
else
m_min.push(m_min.top());
}
void Pop()
{
assert(m_data.size >0 && m_min.size() > 0);
m_data.pop();
m_min.pop();
}
T Min()const
{
assert(m_data.size() >0 && m_min.size() > 0);
return m_min.top();
}
private:
stack<T> m_data; //数据栈
stack<T> m_min; //最小的数据栈
};
//测试
void main()
{
StackWithMin<int> st;
st.Push(9);
st.Push(2);
st.Push(6);
st.Push(4);
st.Push(3);
cout << st.Min() << endl;
}
2.用两个栈实现一个队列
思路:定义两个栈st1,st2,st1栈专门入数据,st2栈专门出数据。无论st1有没有数据直接入数据,如果st2有数据则出数据,没有数据则将st1的数据“倒入”st2中
#include<iostream>
using namespace std;
#include<stack>
template<class T>
class CQueue
{
public:
void appendTail(const T&x) //从队尾插入数据
{
st1.push(x);
}
T deleteHead() //删除头结点
{
if (st2.size() <= 0)
{
while (!st1.empty())
{
T value=st1.top();
st1.pop();
st2.push(value);
}
}
if (st2.size() > 0)
{
T head = st2.top();
st2.pop();
return head;
}
}
private:
stack<T> st1;
stack<T> st2;
};
//测试
void main()
{
CQueue<int> cq;
cq.appendTail(1);
cq.appendTail(2);
cq.appendTail(3);
cq.appendTail(4);
cout << cq.deleteHead() << endl;
}
3.用两个队列实现一个栈
思路:一个队列q1专门负责入数据,只要有数据就入,将队列q1中的元素入到辅助队列q2中,直到q1中只剩下最后一个元素,将这个元素出队列,即实现了出栈
#include<iostream>
using namespace std;
#include<queue>
template<class T>
class CStack
{
public:
void appendHead(const T&x) //从栈顶插入元素
{
q1.push(x);
}
T deleteTail() //从栈顶删除元素
{
if (q2.size() <= 0)
{
while (q1.size()-1)
{
T value = q1.front();
q1.pop();
q2.push(value);
}
}
T tail = q1.front();
q1.pop();
return tail;
}
private:
queue<T> q1;
queue<T> q2;
};
//测试
void main()
{
CStack<int> st;
st.appendHead(5);
st.appendHead(2);
st.appendHead(3);
st.appendHead(9);
st.appendHead(3);
st.appendHead(2);
cout << st.deleteTail() << endl;
}