剑指Offer-面试题22:栈的压入、弹出序列

题面:《剑指Offer》P134 / 牛客网

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

分析清楚两个序列的关系问题就能迎刃而解


方法1

第一个弹出栈的位置无限制,假设为cur。之后元素出栈要更新cur。

此后每一个出栈元素有两种选择

1、入栈队列cur左边第一个相邻未出栈的,如4,5,3,2,1中5出栈后,左边第一个应该是3不能是1,所以序列4,3,5,1,2不对

2、入栈队列cur右边未出栈的,不需要相邻

设置辅助bool列表记录入栈队列的元素是否已出栈

bool IsPopOrder(vector<int> pushV, vector<int> popV) 
{
	int n = popV.size(),cur=0,temp;
	if (pushV.size() != n)
		return false;
	vector<bool> hasPop(n,false);
	bool hasFind;
	for (int i = 0; i < n; i++)
	{
		hasFind = false;
		temp = cur;
		
		while (cur > 0 && hasPop[cur])//向左查找
			cur--;
		if (pushV[cur] == popV[i])
		{
			hasPop[cur] = true;
			continue;
		}

		cur = temp;
		for (int j = cur; j < n; j++)//向右遍历查找
		{
			if (hasPop[j])
				continue;
			if (pushV[j] == popV[i])
			{
				hasPop[j] = true;
				cur = j;
				hasFind = true;
				break;
			}
		}
		 
		if(!hasFind)
			return false;
	}
	return true;
}


方法2

借用辅助栈,根据出栈序列还原出栈过程

如4,5,3,2,1第一个出栈是4,所以在此之前入栈序列1,2,3,4,5中4前面的1,2,3必须先入栈

bool IsPopOrder(vector<int> pushV,vector<int> popV)
    {
        int n = popV.size(),cur=0;
        if (n==0||pushV.size() != n)
            return false;
        stack<int>  s;
        for (int data : popV)
        {
            if (!s.empty() && s.top() == data)
            {
                s.pop();
                continue;
            }
            if (cur == n)
                break;
            while (cur < n&&pushV[cur] != data)
                s.push(pushV[cur++]);
            //s.push(data);
            //s.pop();
            cur++;
        }
        return s.empty();
    }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章