栈和列表面试题2【菜鸟学习日记】

本文介绍了一个算法,用于判断给定的入栈和出栈序列是否合法。通过使用一个辅助栈,该算法能够验证序列的有效性,并提供了一种实现两个栈的数据结构示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开篇接说明,接着上次没有写完的题接着写


题目:判断元素出栈、入栈顺序的合法性。

如:入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1)是合法序列,入栈的序列(1,2,3,4,5),出栈序列为(1,5,3,2,4)是不合法序列

出栈(4,5,3,2,1),怎么出的1,2,3,4入栈,4出栈,入栈5,5出栈,然后3,2,1出栈,这种情况也是合法的,不是只有(5,4,3,2,1)才合法。
这个问题要借助一个临时栈来完成

这里写图片描述

####遍历将in里的数入栈tmp,每入栈一个数,要检查,当入栈的数与out里的数相等时,就pop,并将out++,核对下一个数


bool JudgeLegal(vector<int> in,vector<int> out)
{
    //1、长度是否一样
    if (in.size() != out.size())
    {
        return false;
    }
    //2、长度一样,遍历比较
    //借助一个临时栈
    else
    {
        stack<int> tmp;
        size_t outindex = 0;
        for (size_t i = 0; i < in.size(); i++)
        {
            //入栈
            tmp.push(in[i]);
            //入栈后,检查,相等时,Pop掉,并++,核对下一个数
            while (!tmp.empty()&&tmp.top() == out[outindex])
            {
                tmp.pop();
                outindex++;
            }
        }
        return (tmp.size()>0) ? false : true;
    }
}


void test4()
{
    vector<int> in;
    in.push_back(1);
    in.push_back(2);
    in.push_back(3);
    in.push_back(4);
    in.push_back(5);


    vector<int> out;
    out.push_back(4);
    out.push_back(5);
    out.push_back(3);
    out.push_back(2);
    out.push_back(1);

    if (JudgeLegal(in, out) == true)
        cout << "合法" << endl;
    else
        cout << "不合法" << endl;
}

这里写图片描述


用一个数组实现两个栈

template <class T>
class  ArrTwoStack
{
public:
   ArrTwoStack()
       :_a(new T[3])
       , _capacity(3)
       ,sta1_index(0)
       ,sta2_index(2)
    {}


    //从头走
    void Stack1_Push(const T&x)
    {
        CheckCapacity();
        _a[sta1_index++]=x;

    }

    //从尾走
    void Stack2_Push(const T&x)
    {
        CheckCapacity();
        _a[sta2_index--] = x;
    }

    size_t Stack1_Size()
    {
        return sta1_index;
    }
    size_t Stack2_Size()
    {
        return _capacity - (sta2_index + 1);
    }

    const T& Sta1_Top()
    {
        return _a[sta1_index-1];
    }
    const T& Sta2_Top()
    {
        return _a[sta2_index+1];
    }

    void Sta1_Pop()
    {
        sta1_index--;
    }
    void Sta2_Pop()
    {
        sta2_index++;
    }
protected:
    void CheckCapacity()
    {
        //空间未满不用开空间
        if (sta2_index-sta1_index> 0)
        {
            return;
        }
        //满了,扩容
        else
        {
            //重新开空间
            size_t newCapacity = _capacity * 2;
            T * new_a = new T[newCapacity];

            //拷贝
            //stack1 从前拷贝
            for (size_t i = 0; i <sta1_index; i++)
            {
                new_a[i] = _a[i];
            }

            //stack2 从后拷贝
            for (size_t j = newCapacity - 1; j > sta2_index+(newCapacity-_capacity); j--)
            {
                size_t index = _capacity - 1;
                new_a[j] = _a[index];
                index--;
            }
            /*{
                new_a[j] = _a[_capacity - 1];
                _capacity--;
            }*/
            //犯的错:for循环的条件,在{}内改变造成错误,应在{}重新设临时变量

            _a = new_a;
            sta2_index = sta2_index + (newCapacity - _capacity);
            _capacity = newCapacity;
        }

    }
private:
    T* _a;
    size_t _capacity;//容量
    size_t sta1_index;//sta1下标
    size_t sta2_index;//sta2下标
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值