【数据结构】栈和队列面试题

1、实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最
小值的操作)的时间复杂度为O(1)
针对这个问题我们可以有两种方法来解决,第一种方法:
我们每次压栈的时候压两个数字,先压数据,然后压最小值,每次压之前和数据比较一下,如果数据比最小值还小就把最小值更新成数据,然后再压数据和最小值,这就是压栈操作。这样可以保证栈顶就是最小值。
接下来是出栈操作,因为我们每次多压了一个数据所以出栈的时候要多出一个,每次弹出两个数据,一个是最小值,一个是原数据。
最小值每次只要取最小值就可以了。
这里写图片描述
第二种方式:
我们使用一个辅助栈,压栈的时候,刚开始两个栈都空的的情况下,两个栈同时压栈操作,接下来每次压栈,先判断插入的数据是否比第二个栈的栈顶小,小得话两个栈同时压栈,否则只对第一个栈进行压栈,直到所有数据都被插入。
这里写图片描述
使用两个栈实现一个队列
入队列时,我们直接对栈1进行压栈操作就可以了,
出队列时,如果栈1不为空栈2为空,就把栈1所有元素都出栈,都压入栈2中,每次出队列,对栈2执行出栈操作,直到栈2元素全部弹出,然后再执行前面的操作。
这里写图片描述
使用两个队列实现一个栈
入栈时先看队列1是不是空,队列1不为空直接入队列,如果为空队列2入队列,
出栈时,如果队列1为空,就把队列2除过最后一个以外的所有元素,都入到第一个队列,然后把队列2剩下的最后一个元素弹出,如果队列1不为空就把队列1除过最后一个元素其他元素都入第二个队列,然后弹出队列1最后一个元素,总之,出栈操作就是把队列只剩要出栈的元素其他全部搬移,然后再将这个元素出队列即可
这里写图片描述
元素出栈、入栈顺序的合法性。如入栈的序列(1,2,3,4,5),出
栈序列为(4,5,3,2,1)
要验证出栈顺序的合法性,还是的通过一个栈来验证,我们用一个函数来验证,函数总共四个参数,一个数组用来保存入栈序列,另一个数组用来保存待验证的出栈序列,另外两个参数是这两个序列的大小,首先我们直到出栈入栈元素个数肯定是不变的,所以一进入函数先判断两个序列的大小是否相等,如果连大小都不相等就不用进行下面操作了,直接返回就好了,如何相等的话再进行下面的操作,定义一个循环对入栈序列进行入栈操作,还要设置一个内循环,当栈顶元素和出栈序列元素相同时栈执行出栈操作,输出序列向后走,如果不满组循环条件就一直入栈。如果出栈序列是合法的那么入栈的元素也会都被弹出所以,栈就是空的,所以最后再判断一下,栈是否为空,为空的话表示,出栈序列是合法的,否则就是不合法的。
这里写图片描述
一个数组实现两个栈(共享栈)
我们这里栈的实现是两个栈的栈底在数组的两端,当两个栈的大小之和大于等于总容量的时候,将执行扩容操作,将整片空间扩大至原来的两倍,然后将两个栈的元素都搬到新的空间中,出栈的时候改变当前位置即可。
这里写图片描述

代码以及测试用例如下:

#include<iostream>
#include<stack>
#include<queue>
using namespace std;

//实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最
//小值的操作)的时间复杂度为O(1)
//方法一
class Stack1
{
public:
    void Push(int data)
    {
        if (_s.empty())
        {
            _min = data;
        }
        else
        {
            if (data < _min)
                _min = data;
        }
        _s.push(data);
        _s.push(_min);
    }
    void Pop()
    {
        if (_s.empty())
            return;
        _s.pop();
        _s.pop();
    }
    int Min()
    {
        if (_s.empty())
            return -1;
        return _s.top();
    }
private:
    stack<int> _s;
    int _min;
};
class Stack2
{
public:
    void Push(int data)
    {
        _s1.push(data);
        if (_s2.empty() || data < _s2.top())
            _s2.push(data);
    }
    void Pop()
    {
        if (_s1.empty() && _s2.empty())
            return;
        if (_s1.top() == _s2.top())
        {

            _s2.pop();
        }

            _s1.pop();
    }
    int Min()
    {
        if (_s1.empty())
            return -1;
        return _s2.top();
    }
private:
    stack<int> _s1;
    stack<int> _s2;

};
//使用两个栈实现一个队列
class Queue
{
public:
    void Push(int data)
    {
        _s1.push(data);
        cout << "top" << _s1.top() << endl;
    }
    void Pop()
    {

        if (!_s2.empty())
            _s2.pop();
        else
        {
            while (!_s1.empty())
            {
                int tmp = _s1.top();
                cout <<"pop"<< tmp << " ";
                _s1.pop();
                _s2.push(tmp);
            }
            cout << "Top" << _s2.top() << endl;
        }
    }

private:
    stack<int> _s1;
    stack<int> _s2;
};
//使用两个队列实现一个栈
class Stack
{
public:
    void Push(int data)
    {
        if (!_q1.empty())
            _q1.push(data);
        else
            _q2.push(data);
    }
    void Pop()
    {
        if (_q1.empty())
        {
            while (_q2.size() > 1)
            {
                int tmp = _q2.front();
                _q2.pop();
                _q1.push(tmp);
            }
            _q2.pop();
        }
        else
        {
            while (_q1.size() > 1)
            {
                int tmp = _q1.front();
                _q1.pop();
                _q2.push(tmp);

            }
            _q1.pop();
        }



    }
private:
    queue<int> _q1;
    queue<int> _q2;
};
//元素出栈、入栈顺序的合法性。如入栈的序列(1, 2, 3, 4, 5),出
//栈序列为(4, 5, 3, 2, 1)
bool Legal(int input[], int output[],int in_len,int out_len)
{
    if (in_len != out_len)
        return false;
    stack<int> s;
    int i = 0;
    int j = 0;
    for (; i < in_len; i++)
    {
        s.push(input[i]);
        while (s.size()>0 && s.top() == output[j])
        {
            s.pop();
            j++;
        }
    }
    return (s.size() > 0 ? false : true);
}
//一个数组实现两个栈(共享栈)
class ShareStack
{
public:
    ShareStack()
        :_array(new int[2]),
        _size1(0),
        _size2(1),
        _capacity(2)
    {}
    ~ShareStack()
    {
        if (_array != NULL)
        {
            delete[] _array;
            _array = NULL;
            _size1 = 0;
            _size2 = 0;
            _capacity = 0;
        }
    }
    void Push1(const int& data)
    {
        Capacity();
        _array[_size1] = data;
        _size1++;
    }
    void Push2(const int& data)
    {
        Capacity();
        _array[_size2] = data;
        _size2--;
    }
    void Pop1()
    {
        if (_size1 > 0)
        {
            _size1--;
        }
    }
    void Pop2()
    {
        if (_size2 != _capacity - 1)
            _size2++;
    }
    int Size1()
    {
        return _size1;
    }
    int Size2()
    {
        return _capacity - 1 - _size2;
    }
    int Top1()
    {
        return _array[_size1-1];
    }
    int Top2()
    {
        return _array[_size2+1];
    }
    bool Empty1()
    {
        return _size1 == 0;
    }
    bool Empty2()
    {
        return _size2 == _capacity - 1;
    }
    void Display1()
    {
        if (_size1 > 0)
        {
            for (int i = _size1 - 1; i >= 0; i--)
            {
                cout << _array[i] << " ";
            }
            cout << endl;
        }

    }
    void Display2()
    {
        if (_size2 > 0)
        {
            for (int i = _size2+1; i < _capacity; i++)
            {
                cout << _array[i] << " ";
            }
            cout << endl;
        }

    }
private:
    void Capacity()
    {
        if ((Size1() + Size2()) >= _capacity)
        {
            int newcapacity = _capacity * 2;
            int * tmp = new int[newcapacity];
            int k = newcapacity - 1;
            for (int i = 0; i < _size1; i++)
            {
                tmp[i] = _array[i];
            }
            for (int i = _capacity - 1; i>_capacity - _size2; i--)
            {
                tmp[k] = _array[i];
                k--;
            }
            delete[] _array;
            _size2 = newcapacity - (_capacity - _size2);
            _capacity = newcapacity;
            _array = tmp;
        }
    }
    int *_array;
    int _size1;
    int _size2;
    int _capacity;
};


void Test1()
{
    Stack1 s;
    s.Push(3);
    s.Push(6);
    s.Push(4);
    s.Push(2);
    s.Push(5);

    cout << s.Min() << endl;
    s.Pop();
    s.Pop();
    cout << s.Min() << endl;
}
void Test2()
{
    Stack2 s;
    s.Push(3);
    s.Push(6);
    s.Push(4);
    s.Push(2);
    s.Push(5);

    cout << s.Min() << endl;
    s.Pop();
    s.Pop();
    cout << s.Min() << endl;
}
void Test3()
{
    Queue q;
    q.Push(2);
    q.Push(6);
    q.Push(1);
    q.Push(3);
    q.Push(5);
    q.Pop();

}
void Test4()
{
    Stack s;
    s.Push(2);
    s.Push(6);
    s.Push(1);
    s.Pop();
    s.Push(3);
    s.Push(5);
    s.Pop();

}
void Test5()
{
    int input[] = { 1, 2, 3, 4, 5 };
    int output1[] = { 4, 5, 3, 2, 1 };
    int output2[] = { 4, 5, 3, 1, 2 };
    int in_len = sizeof(input) / sizeof(input[0]);
    int out_len1 = sizeof(output1) / sizeof(output1[0]);
    int out_len2 = sizeof(output2) / sizeof(output2[0]);
    if (Legal(input, output1, in_len, out_len1))
        cout << "合法\n" << endl;
    else
        cout << "不合法\n" << endl;
    if (Legal(input, output2, in_len, out_len2))
        cout << "合法\n" << endl;
    else
        cout << "不合法\n" << endl;
}
void Test6()
{
    ShareStack s;
    s.Push1(1);
    s.Push1(2);
    s.Push1(3);
    s.Push1(4);
    s.Push1(5);
    s.Push1(6);
    s.Push1(7);
    s.Display1();
    s.Pop1();
    s.Display1();
    cout << "Stack1 Top:" << s.Top1() << endl;
    cout << "Stack1 Size:" << s.Size1() << endl;

    cout << endl;

    s.Push2(7);
    s.Push2(8);
    s.Push2(9);
    s.Push2(10);
    s.Display2();
    s.Pop2();
    s.Display2();
    cout << "Stack2 Top:" << s.Top2() << endl;
    cout << "Stack2 Size:" << s.Size2() << endl;
}
int main()
{
    //Test1();
    //Test2();
    //Test3();
    //Test4();
    //Test5();
    Test6();

}

猜你喜欢

转载自blog.csdn.net/flowing_wind/article/details/81356804