剑指offer面试题31——栈的压入、弹出序列

题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列{1,2,3,4,5}是某栈的压栈序列,序列{4,5,3,2,1}是该压栈序列对应的一个弹出序列,但{4,3,5,1,2}就不可能是该压栈序列的弹出序列。

 

思路:

       这道题我开始都没看懂是什么意思,序列{1,2,3,4,5}压栈之后,出栈不就是{5,4,3,2,1}?原来题目是说,压栈的时候是这个顺序,但是可以在压栈的过程中穿插出栈操作,比如先压入1,2,3,4再出栈4,再压栈5,再出栈5、3、2、1,这样就得到了出栈序列{4,5,3,2,1}。明白了这个过程之后,建立一个辅助栈,输入的序列为两个数组结构的数据,分别表示压栈顺序和出栈的顺序,把输入的第一个序列中的数字依次压入该辅助栈,并且按照第二个序列的顺序依次从该栈中弹出序列。首先在空的辅助栈里面压入序列一的第一个数字1,发现1和序列二的第一个数字4不相等,那么就不断的将序列一剩下的数压入辅助队列,直到压入的数也为4,如果序列一全部数字都压入辅助序列后也没有找到相等的数字(这里为4),那么这个序列肯定不是一个有效的弹出序列。这里目前压入辅助栈的数字为1、2、3、4,这个时候我们将辅助序列和第二个序列的栈首数字4同时出栈,第二个序列的首元素变成了5,和辅助栈的首元素3不相等,那么就继续从序列一中压入元素,直到压入5为止,这个时候辅助栈的序列为1 2 3 5,栈首元素和第二栈的首元素相等,那么辅助栈和第二个序列同时将5出栈,此时,辅助栈变为了1 2 3 ,第二个栈也变成了1 2 3,这个时候同时再出栈3 ,又发现栈的首元素都为2,继续出栈2,接着出栈1,这个时候辅助栈为空,序列二也为空,说明第二个序列是第一个序列的辅助序列。

 

代码:

bool IsPopOrder(const int* pPush, const int* pPop, int nLength)
{
	bool bPossible = false;
	if (pPush != nullptr&&pPop != nullptr&&nLength > 0)
	{
		const int* pNextPush = pPush;
		const int* pNextPop = pPop;

		std::stack<int>stackData;

		while (pNextPop-pPop<nLength)
		{
			while (stackData.empty() || stackData.top() != *pNextPop)
			{
				if (pNextPush - pPush == nLength)
					break;
				stackData.push(*pNextPush);

				pNextPush++;
			}

			if (stackData.top() != *pNextPop)
				break;

			stackData.pop();
			pNextPop++;

		}
		if (stackData.empty() && pNextPop - pPop == nLength)
			bPossible = true;
	}
	return bPossible;


}

还是要注意输入的数组指针为空,或者数组的长度小于等于0的情况的处理。

复习:

这里辅助栈的应用很巧妙,用法要记住。

二刷代码:

bool IsPopOrder(const int* pPush, const int* pPop, int nLength)
{
	if (pPop == nullptr || pPop == nullptr||nLength<=0)
		return false;

	bool bPossible = false;

	const int* pNextPush = pPush;
	const int* pNextPop = pPop;

	stack<int>stackData;

	while (pNextPop-pPop<nLength)
	{
		while (stackData.empty()||stackData.top()!=*pNextPop)
		{
			
			if (pNextPush - pPush == nLength)
				break;
			stackData.push(*pNextPush);
			++pNextPush;
		}

		if (stackData.top() != *pNextPop)
			break;
		stackData.pop();
		++pNextPop;
	}

	if (stackData.empty() && pNextPop - pPush == nLength)
		bPossible = true;

	return bPossible;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值