題目描述
輸入一個整數數組,判斷該數組是不是某二叉搜索樹的後序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同。
概念
1、二叉搜索樹:二叉搜索樹(英語:Binary Search Tree),也稱二叉查找樹、有序二叉樹(英語:ordered binary tree),排序二叉樹(英語:sorted binary tree),是指一棵空樹或者具有下列性質的二叉樹:
- 任意節點,如果左子樹不爲空,則左子樹上所有結點的值均小於它的根結點的值;
- 任意節點,如果右子樹不爲空,則右子樹上所有結點的值均大於它的根結點的值;
- 任意節點的左、右子樹也分別爲二叉查找樹;
- 沒有鍵值相等的節點。
2、後序遍歷:後序遍歷首先遍歷左子樹,然後遍歷右子樹,最後訪問根結點,在遍歷左、右子樹時,仍然先遍歷左子樹,然後遍歷右子樹,最後遍歷根結點。
方法一
1、由於是後序遍歷,遍歷順序爲左右根,那麼序列的最後一個節點必爲根節點;
2、根據二叉搜索樹特點:左子樹小於根節點,右子樹大於根節點,可以很容易根據元素與根節點值大小的比較,找出根節點的左子樹及右子樹。然後判斷左子樹節點的值是否都小於根節點的值,右子樹節點的值是否都大於根節點的值,判斷左右子樹對應的序列是否是二叉搜索樹的後序遍歷的結果。很明顯,可以用遞歸的思路去解決問題 。
代碼
class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence) {
if( sequence.empty() )
return false;
return help( sequence, 0, sequence.size()-1 );
}
bool help( vector<int> input, int first, int last )
{
if( last-first <= 1 )
return true;
int small_last = last-1;
while( input[small_last] > input[last] )//找左右子樹分界點
small_last--;
for( int i=first;i<=small_last;i++ )//保證左子樹部分都小於root
if( input[i] > input[last] )
return false;
return help(input, first, small_last) && help(input, small_last+1, last-1 );
}
};
方法二
由於後序遍歷以及二叉搜索樹的特點,對於序列中每一個節點來說,位於該節點之前的節點,從左到右看,應該是連續的小於該節點值,然後是連續的大於該節點的值,如果出現交叉現象,說明該序列不是二叉搜索樹的後序遍歷的結果。描述不太清楚,直接看代碼就好。
代碼
class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence)
{
int length=sequence.size();
if(length==0)
return false;
int i=0;
while(--length)
{
while(sequence[i++]<sequence[length]);
while(sequence[i++]>sequence[length]);
if(i<length)
return false;
i=0;
}
return true;
}
};