• 【编程题目】栈的 push、pop 序列


    29.栈的 push、pop 序列(栈)
    题目:输入两个整数序列。其中一个序列表示栈的 push 顺序,
    判断另一个序列有没有可能是对应的 pop 顺序。
    为了简单起见,我们假设 push 序列的任意两个整数都是不相等的。
    比如输入的 push 序列是 1、2、3、4、5,那么 4、5、3、2、1 就有可能是一个 pop 系列。
    因为可以有如下的 push 和 pop 序列:
    push 1,push 2,push 3,push 4,pop,push 5,pop,pop,pop,pop,
    这样得到的 pop 序列就是 4、5、3、2、1。
    但序列 4、3、5、1、2 就不可能是 push 序列 1、2、3、4、5 的 pop 序列。

    思路:

    首先,我记录了每个pop序列中每一个元素对应在push序列中的位置。这就像是把push序列强制成0 1 2 3 4...一样,这样push序列就是从小到大排列的了。

    然后,观察从小到大排列的push序列,其合理的pop序列的特点。

    4 5 3 2 1

    记录第1个数字 并查找递增的数字 这里是 4  5  他们是递增的。

    3 4 2 1 5

    3 4 5 递增的

    发现只要这些数字符合递增规律,那么pop序列就是合理的。且这些序列就是新加入数字后开始弹出的值。

    还是拿3 4 2 1 5举例

    3 是在压入1 2 3后弹出的第一个值

    4 是在压入4后弹出的第一个值

    5 是在压入5后弹出的第一个值

    4 2 1这个递减的序列表示,没有压入新值,一直在弹出。

    即,有递增序列表示有压入新的值,递减序列表示一直弹出。因为push序列时递增的,故压入的新值只能越来越大。

    对于4、3、5、1、2

    4 5 2 显然不满足递增关系 即压入5后不能再压入2 不是合法的pop序列

    注:我没法证明,不知道是不是所有的都符合这个规律。谁能举出反例吗?

    /*
    29.栈的 push、pop 序列(栈)
    题目:输入两个整数序列。其中一个序列表示栈的 push 顺序,
    判断另一个序列有没有可能是对应的 pop 顺序。
    为了简单起见,我们假设 push 序列的任意两个整数都是不相等的。 
    比如输入的 push 序列是 1、2、3、4、5,那么 4、5、3、2、1 就有可能是一个 pop 系列。
    因为可以有如下的 push 和 pop 序列:
    push 1,push 2,push 3,push 4,pop,push 5,pop,pop,pop,pop,
    这样得到的 pop 序列就是 4、5、3、2、1。
    但序列 4、3、5、1、2 就不可能是 push 序列 1、2、3、4、5 的 pop 序列。
    start time = 16:15
    end time = 17:20 
    */
    
    #include <stdio.h>
    
    int * getlocation(int data, int * poplist, int len)
    {
        for(int i = 0; i < len; i++)
        {
            if(data == poplist[i])
                return poplist + i;
        }
        return NULL;
    }
    bool ispop(int * pushlist, int * poplist, int len)
    {
        for(int i = 0; i < len; i++) //记录pop中的数字对应push中那个位置
        {
            int * loc = getlocation(pushlist[i], poplist, len);
            if(loc != NULL)
            {
                *loc = i;
            }
            else
            {
                printf("error:the two list have different member!");
            }
        }
    
        
        int IncreaseNum2 = poplist[0];
        int IncreaseNum1;
        for(int i = 1; i < len; i++)
        {
            if(poplist[i] > poplist[i - 1])
            {
                IncreaseNum1 = IncreaseNum2;
                IncreaseNum2 = poplist[i];
                if(IncreaseNum2 < IncreaseNum1)
                    return false;
            }
        }
        return true;
    }
    
    int main()
    {
        int a[5] = {1,2,3,4,5};
        int b[5] = {5,3,4,2,1};
        bool is = ispop(a, b, 5);
        return 0;
    }

    网上答案:网上的思路惊人的一致,都是直接的建一个栈来模拟这个过程。比我的思路来的要好,计算少,又好理解。

    http://blog.sina.com.cn/s/blog_a46817ff01019vtd.html

     如果我们希望pop的数字正好是栈顶数字,直接pop出栈即可;如果希望pop的数字目前不在栈顶,我们就到push序列中还没有
     * 被push到栈里的数字中去搜索这个数字,并把在它之前的所有数字都push进栈。如果所有的数字都被push进栈仍然没有找到这
     * 个数字,表明该序列不可能是一个pop序列。

    网上随便找了个代码,还没验证http://www.cnblogs.com/aLittleBitCool/archive/2011/03/05/1971689.html

    //栈的push、pop序列
    
    #include<iostream>
    #include<stack>
    const int SIZE=5;                  //定义长度
    using namespace std;
    bool judge(int Spush[],int Spop[]){
        stack<int> my_stack;
        int iPush=0,iPop=0;
        while(iPush<SIZE){                //当栈顶和pop相等时,将pop后的栈顶与pop之后的元素相比,直到不等
            cout<<"push "<<Spush[iPush]<<endl;         //测试
            my_stack.push(Spush[iPush]);
            while(!my_stack.empty()&&iPop!=5&&my_stack.top()==Spop[iPop]){  //小心数组越界
                cout<<"pop "<<Spop[iPop]<<endl;      //测试
                iPop++;
                my_stack.pop();
            }
            iPush++;
        }
        if(iPop==SIZE) return true;
        else return false;
    }
    int main(void){
        int Spush[SIZE],Spop[SIZE];
        for(int i=0;i<SIZE;i++)
            cin>>Spush[i];
        for(int i=0;i<SIZE;i++)
            cin>>Spop[i];
        if(judge(Spush,Spop)) cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
        system("pause");
        return 0;
    }
  • 相关阅读:
    winform窗口打开特效及窗口位置居中
    C# Installer Projects 打包工具
    C#
    MVVM模式开发WinForm-ReactiveUI
    C#实现类似百度网盘、育网校园云盘在“我的电脑”磁盘驱动器
    MVVM框架
    自制2048小游戏
    一个无限循环轮播图 HCCycleView
    Xcode插件及cocoapods不能正常使用的解决方法
    Runtime — 运行时机制
  • 原文地址:https://www.cnblogs.com/dplearning/p/3981828.html
Copyright © 2020-2023  润新知