劍指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();
    }


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