针对数组题解(C++)

栈的压入、弹出序列

http://www.nowcoder.com/questionTerminal/d77d11405cc7470d82554cb392585106

语言:C++

算法思路:考虑到大家都用的是栈的方法,我这里写一种针对数组的方法。这题的关键在于判断每次popV数组每次弹出的值是否在pushV数组中可能被弹出。我的判断方法是:设置一个int型指针p_push,它指的是每上一次popV数组弹出的值在pushV数组中对应的下标,那么这次popV数组弹出的值就必须是pushV数组中这个下标p_push右边(>p_push)或者是左边第一个可以被弹出的值。讲的有点绕,下面举个例子。
比如压入栈的序列是1 2 3 4 5,判断序列4 5 3 2 1可否是弹出序列。参见下图
step1:找到第一个弹出的数字4在pushV数组中的位置下标3,并将该位置判断为已弹出过(程序中用的是judge数组,以后每一步弹出一个值后都要标记);
step2:找到要弹出的值5,从上一步记录的位置p_push下标3,向左找到第一个可以被弹出的位置,记为p_left下标2。那么p_left位置左边的数字在这一步中都不可以被弹出(相当于被p_left对应的值压在下面),而p_left右边的值(包括自身)都有可能被弹出。显然5在p_left右边,故可以被弹出。这时候更新p_push值为下标4。
step3:要弹出的值为3,上一步记录的p_push位于下标4。从它的左边开始寻找第一个可能被弹出的指(由于数值4已经被弹出过,所以再向左移一格到数值3),并记录下标2为p_left。那么同理,p_left左边的数值都不可以在这一步中被弹出,而p_left右边(包括自身)可以被弹出,而3正好是p_left对应的数值,故可以弹出。
step4:···依次类推
图片说明
如果压入序列为1 2 3 4 5, 输出序列是4 3 5 1 2,判断流程依上述原理见下图。可见在step4的时候,要被弹出的值1位于p_left的左边,故不可以被弹出!
图片说明

算法效率:时间O(n*n), 空间O(n)

具体代码

class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {
        int length = pushV.size();
        if (length == 0 || (length == 1 && pushV[0]==popV[0]))  return true; //特殊输入例子

        int i,j,p_push = -1, p_left;
        vector<int> judge;
        for (i=0; i<length; i++)
           judge.push_back(1);
        //找到popV第一个弹出值在pushV中的位置,并复制给p_push;
        for (i=0; i<length; i++)
            if (pushV[i] == popV[0])
            {
                p_push = i;
                judge[i] = 0;
                break;
            }
        if (p_push==-1) return false; // 防止弹出的值在pushV数组中找不到

        // 遍历popV数组每次弹出的值,判断它是否可能被弹出
        for (int i=1; i<length; i++)
        {
            p_left = p_push-1;
            while (p_left>=0 && !judge[p_left])
                --p_left;
            for (j=0; j<p_left; j++)
                if (popV[i] == pushV[j]) return false; //不可能被弹出,false
            for (j = p_left; j<length; j++)
                if (popV[i] == pushV[j]) 
                {
                    p_push = j;
                    judge[j] = 0;
                    break;            //可以被弹出,true
                }
        }
        return true;
    }
};

上述如有问题,欢迎讨论指出,谢谢!

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 春招至今,你的战绩如何? #
10789次浏览 93人参与
# 你的实习产出是真实的还是包装的? #
1925次浏览 42人参与
# 米连集团26产品管培生项目 #
5981次浏览 216人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
7595次浏览 43人参与
# 简历第一个项目做什么 #
31715次浏览 338人参与
# 重来一次,我还会选择这个专业吗 #
433485次浏览 3926人参与
# MiniMax求职进展汇总 #
24068次浏览 309人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
187157次浏览 1122人参与
# 牛客AI文生图 #
21442次浏览 238人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152396次浏览 888人参与
# 研究所笔面经互助 #
118934次浏览 577人参与
# 简历中的项目经历要怎么写? #
310271次浏览 4216人参与
# AI时代,哪些岗位最容易被淘汰 #
63684次浏览 825人参与
# 面试紧张时你会有什么表现? #
30507次浏览 188人参与
# 你今年的平均薪资是多少? #
213095次浏览 1039人参与
# 你怎么看待AI面试 #
180063次浏览 1256人参与
# 高学历就一定能找到好工作吗? #
64328次浏览 620人参与
# 你最满意的offer薪资是哪家公司? #
76504次浏览 374人参与
# 我的求职精神状态 #
448056次浏览 3129人参与
# 正在春招的你,也参与了去年秋招吗? #
363419次浏览 2638人参与
# 腾讯音乐求职进展汇总 #
160651次浏览 1112人参与
# 校招笔试 #
470997次浏览 2964人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务