数据结构-栈和队列面试题(上)

来源:互联网 发布:汕头 知乎 编辑:程序博客网 时间:2024/06/07 03:33

在数据结构的学习过程中,栈和队列的掌握是十分重要的。所以找了几个很热门的面试题试试手并小结一下。先回顾下栈和队列的特性:栈是后进先出,主要接口有PUSH,POP,TOP,而队列是先进先出,主要接口有PUSH,POP,FRONT;


面试题一:使用两个栈实现一个队列


思路:考察的就是对于栈和队列的特性掌握熟练度。两个栈一个为push栈,一个为pop栈。先简述下各接口的思路再画图。
①push:最开始都为空时,随便将push进入一个栈中,之后的每次将数据push到不为空的栈中;
②pop:想要删除一个队列最头部的元素,在本题就转换为删除栈最底部的元素。首先可以将本栈所有元素push进入另一个栈中,假设原来栈从上到下为:4,3,2,1;当push进入另一个栈中就为1,2,3,4;此时这些数据可以一直保留在该栈中,之后的每次pop就从此栈直接进行pop,直到该栈数据删完再此从原始栈中push数据进来;这样就可以保证每次删除的都是栈最底下的元素。
③Front:访问队首元素和pop的问题相类似,一个是要将队首元素删除,一个是要返回,所以也可按照上面思路。

图示思路:

这里写图片描述


实现代码:
class TwoStackToQueue{public:    TwoStackToQueue()    {}    void Push(const int& x)    {        PushStack.push(x);    }    void Pop()    {        if (!PopStack.empty())        {            PopStack.pop();        }        else        {            while (!PushStack.empty())            {                PopStack.push(PushStack.top());                PushStack.pop();            }        }    }    const int& Front()    {        if (!PopStack.empty())        {            return PopStack.top();        }        else        {            while (!PushStack.empty())            {                PopStack.push(PushStack.top());                PushStack.pop();            }            return PopStack.top();        }    }    size_t Size()    {        return PushStack.size() + PopStack.size();    }    bool Empty()    {        return PushStack.empty() && PopStack.empty();    }private:    stack<int> PushStack;    stack<int> PopStack;};
测试:

这里写图片描述


面试题二:使用两个队列实现一个栈


思路:一个队列用来push,一个用来pop。
①push:将数据push到不为空的栈;
②pop:将n-1个数据push到另外一个栈中,剩下的一个元素即为队尾的元素,进行pop即可;
③Top:如同②,先将n-1个元素push到另一个栈,返回最后一个元素后再push进入另一个栈。

图示思路:

这里写图片描述


实现代码:
class TwoQueueStack{public:    TwoQueueStack()    {}    void Push(const int& x)    {        if (q1.empty())            q2.push(x);        else            q1.push(x);    }    void Pop()    {        assert(!q1.empty() || !q2.empty());        if (q1.empty())        {            while(q2.size() > 1)            {                q1.push(q2.front());                q2.pop();            }            q2.pop();        }        else        {            while(q1.size() > 1)            {                q2.push(q1.front());                q1.pop();            }            q1.pop();        }    }    const int& Top()    {        assert(!q1.empty() || !q2.empty());        int tmp = 0;        if (!q1.empty())        {            while (q1.size() > 1)            {                q2.push(q1.front());                q1.pop();            }            tmp = q1.front();            q2.push(tmp);            q1.pop();        }        else        {            while (q2.size() > 1)            {                q1.push(q2.front());                q2.pop();            }            tmp = q2.front();            q1.push(tmp);            q2.pop();        }        return tmp;    }    bool Empty()    {        return q1.empty() && q2.empty();    }    size_t Size()    {        return q1.size() + q2.size();    }private:    queue<int> q1;    queue<int> q2;};
测试:

这里写图片描述


面试题三:实现一个栈,要求实现Push,Pop,Min(返回最小值)的时间复杂度为O(1)


思路:该题的实现方法有很多种,在下面列举出两种不容易出错的方法。①:使用两个栈,一个栈用来正常push数据,pop数据,但是与此同时再使用一个栈来存放对应的最小值,也就是说两个栈中数据数量相同,每次pop,同时对两个栈进行pop即可;②可创建一个键值对pair,first存放插入的数据,scond存放对应此时的最小值。

图示思路过程:

这里写图片描述


代码实现:
//采用方法2class OneStack2{public:    OneStack2()    {}    void Push(const int& x)    {        if (s.empty())        {            s.push(make_pair(x, x));        }        else        {            int min = s.top().second;            if (x < min)            {                s.push(make_pair(x, x));            }            else            {                s.push(make_pair(x, min));            }        }    }    void pop()    {        s.pop();    }    int min()    {        return s.top().second;    }private:    stack<pair<int, int>> s;};class OneStack1{public:    OneStack1()    {}    void Push(const int& x)    {        s.push(x);        if (minStack.size() == 0)            minStack.push(x);        else        {            if (x < minStack.top())                minStack.push(x);            else                minStack.push(minStack.top());        }       }    void pop()    {        if (!s.empty() && ! minStack.empty())        {            s.pop();            minStack.pop();        }    }    int min()    {        if (!minStack.empty())            return minStack.top();        else            return -1;    }private:    stack<int> s;    stack<int> minStack;};

还有小结(下),请点击栈和队列面试题(下)。

原创粉丝点击