栈和队列面试题
1.实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(返回最小值的操作)的时间复杂度为O(1)
2.使用两个栈实现一个队列
3.使用两个队列实现一个栈
4.元素出栈、入栈顺序的合法性。如入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1)
5.一个数组实现两个栈
6. 用递归函数和栈操作逆序对
1.实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(返回最小值的操作)的时间复杂度为O(1)
思想:
借助两个栈,一个栈是数据栈,一个栈用来存取最小值。
1. Push(入栈):S1实现入栈,存储数据。而S2是实现返回最小值的栈(S2.top()),其中S2的入栈条件是:为空的时候或者S1入栈的值比S2.top()大时
2. Pop(出栈) :为了方便,两个栈的大小相同,一起pop。我们在S2入栈条件不符合的时候,将自己的top()再次入栈,这样保证了S2的栈顶一直都是最小值,且Pop时方便。
3. Min(返回最小的值):S2.top()就是栈中最小值。
template <class T>
class MinStack
{
public:
void Push(const T& x)
{
S1.push(x);
if(S2.empty() || x < S2.top())
{
S2.push(x);
}
else
{
S2.push(S2.top());
}
}
void Pop()
{
S1.pop();
S2.pop();
}
T& Min()
{
return S2.top();
}
size_t Size()
{
return S1.size();
}
T& Top()
{
return S1.top();
}
bool Empty()
{
return S1.empty();
}
protected:
stack<T> S1;
stack<T> S2;
};
2.使用两个栈实现一个队列
思想:
用一个栈实现Push,用另外一个栈实现Pop,而实现Pop的栈的栈顶就是队头Front.
1.Push:S1来实现。
2.Pop:S2来实现。过程就是:当S2为空的时候,将S1中的值一一pop然后入栈push到S2,直到S1为空,其中S2.top()就是队列要Pop的值。而S2非空时,直接S2.top()
3.Front : S2非空时:S2.top()就是队头front;当S2为空时,将S1中的值一一入栈到S2,最后S2.top()就是front.
template <class T>
class QueueByTwoStack
{
public:
void Push(const T& x)
{
S1.push(x);
}
void Pop()
{
if(S1.empty()&&S2.empty())
return;
if (S2.empty())
{
while (!S1.empty())
{
S2.push(S1.top());
S1.pop();
}
}
S2.pop();
}
T& Front()
{
if (S2.empty())
{
while (!S1.empty())
{
S2.push(S1.top());
S1.pop();
}
}
return S2.top();
}
size_t Size()
{
return S1.size()+S2.size();
}
bool Empty()
{
return S1.empty()&&S2.empty();
}
protected:
stack<T> S1;