今天来说几道简单的栈和队列相关的几道面试题:
1 . 实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(返回最小值的操作)的时间复杂度为O (1 )
第一道题,我们需要分析,我想一般的思维肯定是想到,开辟一块空间,进行保存最小值,这种方法也是大家通常地一下就可以想到的。但是在这里会有一个问题,就是如果你的最小值在栈顶,当你pop了栈顶以后,下面的数据中最小的元素就会发生改变,这个时候你无法得到新的最小的元素了。
所以,我们给出一种解决思路:就是你需要有两个栈,一个保存数据,一个辅助作为保存最小值情况的栈。,然后当我们进行push的时候,如果辅助最小值的栈也是空的,那么就push,不是空的时候和最小值栈的栈顶进行比较,如果比它小,再进行压栈,否则,就不用push。在pop的时候,这个时候我们需要和栈顶比较,如果pop的数值和栈顶是一样大的话,那么久吧保存数据的栈和最小值的栈的栈顶都进行pop。
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<iostream>
#include<cstdlib>
#include<cassert>
#include<stack>
#include<vector>
using namespace std;
template<typename T>
class Stack
{
public:
void push(const T& d);
void pop();
T& min();
private:
stack<T>DataStack;
stack<T>MinStack;
};
template<typename T>
void Stack<T>::push(const T& d)
{
DataStack.push(d);
if (MinStack.empty() || d <= MinStack.top())
{
MinStack.push(d);
}
}
template<typename T>
void Stack<T>::pop()
{
assert(!DataStack.empty());
if (DataStack.top() == MinStack.top())
{
DataStack.pop();
MinStack.pop();
}
DataStack.pop();
}
template<typename T>
T& Stack<T>::min()
{
return MinStack.top();
}
2 . 使用两个栈实现一个队列
对于这个问题的分析,我们可以转换为两个栈之间的来回循环倒的一个问题。
在这,我们应该清楚,两个数据结构的数据特性,一个是先进后出,一个是后进先出,所以,我们在这里可以这样分析:
当我们入队操作的时候,对第一个栈进行压栈,如果我们想要pop的时候,这个时候其实是要pop的是第一个栈的栈底元素,所以这个时候我们把第一个栈栈顶元素push进入第二个栈,然后pop,这样依次到第一个栈空。然后我们再pop第二个栈顶元素的top,这样就是实现了出队。