栈面试题

来源:互联网 发布:淘宝上下架时间设置 编辑:程序博客网 时间:2024/05/21 01:47

     问题描述,实现一个栈,要求push,pop,min(返回最小值的操作)的时间复杂度为O(1)。

     


     思路1:模拟实现一个栈,在成员变量中一个int类型的变量,用来保存最小值,每当push一个数据,都将push的数据与变量中保存的数据进行对比,如果,push数据小于保存的值,那么就将最小值更新为push进来的数据,反之,则不用替换。假想push(2,3,4,1),那么最后保存的最小值是1,时间复杂度也将会是1,因为操作的次数为常数。但是这种思路是错误的,原因在于,pop数据的时候不会更新最小数据,试想上面的例子,将1 pop出去,那么最小的值就变成了2,可是变量里面还是1,没有更新数据导致程序逻辑错误。

     思路2:使用两个栈结构来维护两段内存,一个存储正常push的数据,一个存储最小数据。

那么,这么样就不用为更新最小数据而头疼。

    1.定义一个类似栈结构的结构体(当然可以实现为模板将会更加方便)

    typedef struct _stack    {    _stack()    :_capacity(5)    , _size(0)    {    _array = new int[5];    }        ~_stack()    {    if (_array)    {    delete[] _array;    _array = NULL;    }    }        int* _array;//存储数据的数组    int _capacity;//容量    int _size;//有效数据    }stack;

    2.定义一个类来管理两个结构体的对象

    class Stack    {    public:    Stack()     :s()    , minstack()    {}        bool pop(int* e)    {    if (s._size == 0)    {    return false;    }        int value = s._array[--s._size];        if (value == minstack._array[minstack._size - 1])    {    --minstack._size;    }    *e = value;        return true;    }        bool push(int value)    {        if (s._size >= s._capacity)    {    s._capacity = s._capacity * 2;    int* tmp = new int[s._capacity];    int* cmp = new int[s._capacity];    for (int i = 0; i < s._size; i++)    {    tmp[i] = s._array[i];    }    for (int i = 0; i < minstack._size; i++)    {    cmp[i] = minstack._array[i];    }    delete[] s._array;    delete[] minstack._array;        s._array = tmp;    minstack._array = cmp;    }        /*    if (s._size == s._capacity)    {    return false;    }    */      if (minstack._size == 0 || value <= minstack._array[minstack._size - 1])    {    minstack._array[minstack._size++] = value;    }        s._array[s._size++] = value;    return true;    }        bool min(int* pMin)    {    if (minstack._size == 0)    {    return false;    }        *pMin = minstack._array[minstack._size - 1];    return true;    }    private:    stack s;      //用来维护正常数据栈    stack minstack;  //用来维护最小数据栈    };

    3.push函数实现细节

1).s维护的内存,正常压入数据

2).minstack维护的内存,当minstack._size == 0的时候,压入第一个数据,当要压入第二个数据的时候,需要和minstack维护的栈的top数据进行比较,如果压入数据比当前minstack的top数据小,则压入,否则则不压入。

wKioL1cI4RXiU9qrAAAusiZ8_SM269.png    左边为s维护的栈结构,右边为minstack维护的栈结构


    4.pop函数的实现细节

1).首先由push会知道 s.top() >= minstack.top() 是恒成立的。

2).取到即将要被s栈即将要被pop出去的数据,用数据与minstack栈顶元素作比较,如果s.top() > minstack.top() 则只将s栈的栈顶元素pop出去而不用pop minstack的栈顶元素。如果s.top() == minstack.top(),则将s栈和minstack栈 的元素统统pop出去。

wKioL1cI6znzGUbOAAAwRKD8bNQ669.png

     5.min实现细节

1).返回minstack的栈顶元素

wKiom1cI6siA_KFFAAAsZSt-uts655.png

    6.测试用例

    void Test()    {    Stack s;    s.push(9);    s.push(7);    s.push(10);    s.push(5);    s.push(8);    s.push(1);    cout << "压入序列9 7 10 5 8 1" << endl;    cout << "弹出序列" << endl;    int value;    while (s.pop(&value))    {    cout << "pop  " << value << "\t";    if (s.min(&value))    cout << "min value : " << value << endl;    else    cout << "there is no min value!" << endl;    }    }

    以上就是本人在做本道面试题的一些想法,分享给大家。

本文出自 “做一个小小小司机” 博客,请务必保留此出处http://10799170.blog.51cto.com/10789170/1762137

0 0
原创粉丝点击