判断一个出栈序列是否合法

1、要求

给定一个入栈序列和一个出栈序列,判断这个出栈序列是否合法。

例如:

入栈序列:pushV:[1, 2, 3, 4, 5, 6, 7]

出栈序列:popV:[1, 3, 2, 5, 7, 6, 4]

2、实现思路

我们使用栈模拟的方式来做这道题:

  • 使用一个辅助栈来模拟出入栈的过程

  • 用两个指针来遍历出栈序列和入栈序列

    1. 指针 i 用来遍历入栈序列,开始指向1(入栈序列的第一位)。

    2. 指针j用来遍历出栈序列,开始指向1(出栈序列的第一位)。

    3. 对于 1 这个元素,由于 pushV[i] == popV[j]。让 1 入栈后立马出栈就能得到出栈时1的位置。因此我们不管1,直接考虑下个元素(i++,j++)。

    4. 对于 3 这个元素,由于 pushV[i] != popV[j]。让 2 入栈后立马出栈显然不合法,所以我们把 2 这个元素入栈后,让 i 继续往后走,一直走到 3 的位置。

    5. 走到 3 的位置后,此时 pushV[i] == popV[j] 。让 3 入栈后立马出栈就能得到 3 的位置,所以我们不管3,直接考虑下个元素(i++,j++)。但是。由于栈中有元素,我们就要考虑栈顶元素是不是出栈序列位置上的元素,如果是,让栈顶弹出,j 指针往后走。直到栈为空或者栈顶元素不是 j 指向的元素。

    6. 重复上述过程,直到 i 指针走到头(i == pushV.size())。

  • 最后如果辅助栈中元素为空,说明这个出栈序列是合法的。否则说明出栈序列非法。

用这个思路分析上面的例子就是:(我们只要盯着出栈序列元素,想办法让入栈元素出栈入栈后尽可能满足出栈序列元素的位置)

  1. 元素1:出栈,入栈。————>输出:1
  2. 元素3: 2入栈,3入栈,3出栈—————>输出3
  3. 元素2:栈中2出栈————>输出2
  4. 元素5: 4 入栈,5入栈,5出栈————>输出5
  5. 元素:7: 6入栈,7入栈,7出栈————>输出7
  6. 元素6:6出栈————>输出6
  7. 元素4: 4出栈————>输出4
  8. 辅助栈空,故出栈序列合法。

3、代码实现

	bool IsPopOrder(vector<int> pushV,vector<int> popV) {
	    stack<int>s;
	    int i = 0;
	    int j = 0;
	    while(i!=pushV.size())
	    {	
	        if(pushV.at(i)!=popV.at(j))
	        {
	        	s.push(pushV.at(i));
	        	i++;
	        }
	        else
	        {
	        	i++;
	        	j++;
	        	while(!s.empty() && popV.at(j)==s.top())
	        	{
	        		s.pop();
	        		j++;
	        	}
	        }
	    }
	    if(!s.empty()) return false;
	    else return true;
	}

4、案例讲解

接下来看道题目:

alt

输入:

[1,3,2]

返回值:

true

说明:

是上图的后序遍历 ,返回true        

4.1 算法思路

  1. 二叉树的中序遍历和后序遍历对应着一种栈的压入、弹出序列,而对于后序遍历从小到大就得到了中序遍历序列。
  2. 我们得到中序遍历序列后,将其作为入栈序列,检查后续遍历是不是一个合法的出栈序列即可(用上面的方法去做)

4.2 代码实现

class Solution {
public:
	bool IsPopOrder(vector<int> pushV,vector<int> popV) {
	    stack<int>s;
	    int i = 0;
	    int j = 0;
	    while(i!=pushV.size())
	    {
	        if(pushV.at(i)!=popV.at(j))
	        {
	        	s.push(pushV.at(i));
	        	i++;
	        }
	        else
	        {
	        	i++;
	        	j++;
	        	while(!s.empty()&&popV.at(j)==s.top())
	        	{
	        		s.pop();
	        		j++;
	        	}
	        }
	    }
	    if(!s.empty()) return false;
	    else return true;
	}
    bool VerifySquenceOfBST(vector<int> sequence) {
    	if(sequence.empty()) return false;
    	vector<int> inOrder(sequence);
    	sort(inOrder.begin(),inOrder.end());
    	return IsPopOrder(inOrder,sequence);
    }
};
数据结构和算法 文章被收录于专栏

该专栏内容包含常见的数据结构和一些算法知识。若有错误请各位指正。 //里面所有代码均通过vscode调试。

全部评论

相关推荐

Beeee0927:是缅甸园区吗
点赞 评论 收藏
分享
程序员小白条:太晚了,看别人找到实习了才投的话,自己本身就没啥准备,计划太晚咯,只能吞苦果子
点赞 评论 收藏
分享
06-27 12:54
已编辑
门头沟学院 Java
累了,讲讲我的大学经历吧,目前在家待业。我是一个二本院校软件工程专业。最开始选专业是觉得计算机感兴趣,所以选择了他。本人学习计算机是从大二暑假结束开始的,也就是大三开始。当时每天学习,我个人认为Java以及是我生活的一部分了,就这样持续学习了一年半,来到了大四上学期末,大概是在12月中旬,我终于找的到了一家上海中厂的实习,但我发现实习生的工作很枯燥,公司分配的活也不多,大多时间也是自己在自学。就这样我秋招末才找到实习。时间来到了3月中旬,公司说我可以转正,但是转正工资只有7000,不过很稳定,不加班,双休,因为要回学校参加答辩了,同时当时也是心高气傲,认为可以找到更好的,所以放弃了转正机会,回学校准备论文。准备论文期间就也没有投递简历。然后时间来到了5月中旬,这时春招基本也结束了,然后我开始投递简历,期间只是约到了几家下场面试。工资也只有6-7k,到现在我不知道该怎么办了。已经没有当初学习的心劲了,好累呀,但是又不知道该干什么去。在家就是打游戏,boss简历投一投。每天日重一次。26秋招都说是针对26届的人,25怎么办。我好绝望。要不要参加考公、考研、央国企这些的。有没有大佬可以帮帮我。为什么感觉别人找工作都是顺其自然的事情,我感觉自己每一步都在艰难追赶。八股文背了又忘背了又忘,我每次都花很长时间去理解他,可是现在感觉八股、项目都忘完了。真的已经没有力气再去学习了。图片是我的简历,有没有大哥可以指正一下,或者说我应该走哪条路,有点不想在找工作了。
码客明:太累了就休息一下兄弟,人生不会完蛋的
如果实习可以转正,你会不...
点赞 评论 收藏
分享
评论
2
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务