栈面试题总结

来源:互联网 发布:淘宝代销退货如处理 编辑:程序博客网 时间:2024/05/02 04:53

1.求栈上的最小值

具体要求:在O(1)的时间复杂度内求出栈上的最小值,并且不受出栈入栈的影响。
思路:借助一个辅助栈,原栈在有数据入栈的时候,辅助栈也有数据入栈。辅助栈入栈的数据为当前的最小值。
实现:

template<typename T>class StackMin{public:    void Push(const T&data);    void Pop();    T Min();private:    stack<T>st1;    stack<T>st2;};template<typename T>void StackMin<T>::Push(const T&data){    st1.push(data);    if (st2.size() == 0 || st2.top() > data)        st2.push(data);    else        st2.push(st2.top());}template<typename T>void StackMin<T>::Pop(){    if (st1.size() == 0)        return;    st1.pop();    st2.pop();}template<typename T>T StackMin<T>::Min(){    return st2.top();}

2.利用两个栈实现队列

具体要求:实现队列的push,pop,front,back操作
思路:栈上的数据为先进后出,队列上的数据为先进先出。可以用栈1专门用来放push的数据,如果要pop的时候,就把栈1的数据存入到栈2中去,对栈2进行pop。
实现:

template<typename T>class QueueOfTwoStack{public:    void Push(const T&data);    void Pop();    T&Front()////可以合并    {        if (st2.empty())        {            while (!st1.empty())            {                st2.push(st1.top());                st1.pop();            }        }        return st2.top();    }    T&Back()    {        if (st1.empty())        {            while (!st2.empty())            {                st1.push(st2.top());                st2.pop();            }        }        return st1.top();    }private:    stack<T>st1;    stack<T>st2;};template<typename T>void QueueOfTwoStack<T>::Push(const T&data){    st1.push(data);}template<typename T>void QueueOfTwoStack<T>::Pop(){    if (st2.size() == 0)    {        int count = st1.size();        for (size_t i = 0; i < count; i++)        {            st2.push(st1.top());            st1.pop();        }        st2.pop();    }    else        st2.pop();}

3.利用两个队列实现栈

具体要求:实现栈的Push,pop,top操作
思路:队列的数据是满足先进先出,栈上的数据满足先进后出。可以用一个队列来接收数据,当要出数据的时候,把前面的数据都放到另一个队列上去,留下最后一个。然后交换两个队列,进行下一波操作。
实现:

template<typename T>class StackWithTwoQueue{public:    void Push(const T&data);    void Pop();    T&Top()    {        assert(!qu1.empty());        return qu1.back();    }private:    queue<T>qu1;    queue<T>qu2;};template<typename T>void StackWithTwoQueue<T>::Push(const T&data){    qu1.push(data);}template<typename T>void StackWithTwoQueue<T>::Pop(){    if (0 == qu1.size())        return;    int count = qu1.size();    for (int i = 0; i < count - 1; i++)    {        qu2.push(qu1.front());        qu1.pop();    }    qu1.pop();    swap(qu1, qu2);//交换}

4.数组判断是否为出栈顺序

具体要求:如果是对的顺序就返回true,否则返回false
思路:借助一个栈来实现,将Push的值挨个入栈,同时进行判断栈顶的值是否与pop的第一个值相等,如果相同就出栈。最后如果栈为空,并且pop的也走到了最后,就说明是出栈顺序。
实现:

bool IsPopOrder(const int*pPush, const int*pPop, int length){    bool ret = false;    if (NULL == pPush || NULL == pPop || length <= 0)        return ret;    const int*pNextPush = pPush;    const int*pNextPop = pPop;    stack<int>s;    while (pNextPop - pPop < length)    {        while (s.size() == 0 || *pNextPop != s.top())        {            if (pNextPush - pPush == length)                break;            s.push(*pNextPush);            pNextPush++;        }        if (s.top() != *pNextPop)            break;        s.pop();        pNextPop++;    }    if (s.empty() && pNextPop - pPop == length)        ret = true;    return ret;}

5.背包问题
具体要求:背包的承重固定,从一系列物品中挑出刚好能放满背包的所有物品。
思路:借助一个栈来实现,栈中放的是物品数组的下标。依次往栈中放元素,如果超过了承重,就将其pop,放入一个元素来比较。
实现:

void backpack(int *arr, int size, int weight){    assert(arr);    int begin = 0;    int sum = 0;    stack<int> s;    int pos = 0;    while (begin < size)    {        if (pos < size)        {            s.push(pos);            sum += arr[pos];            if (sum == weight)            {                Print(arr, s);            }            if (sum > weight)            {                sum -= arr[s.top()];                s.pop();            }            pos++;        }        else        {            sum -= arr[s.top()];            pos = s.top() + 1;            s.pop();        }        if (s.empty())        {            begin++;            pos = begin;            sum = 0;        }    }}
1 0
原创粉丝点击