題目:輸入一個整數數組,判斷該數組是不是某二叉搜索樹的後序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同。
首先要注意二叉搜索樹的定義:二叉搜索樹也成爲有序二叉樹,排序二叉樹,是指一棵空樹或者具有下列性質的二叉樹:1、若任意節點的左子樹不空,則左子樹上所有節點的值均小於它的根節點的值;2、任意節點的右子樹不空,則右子樹上所有節點的值均大於它的根節點的值;3、任意節點的左、右子樹也分別爲二叉查找樹。4、沒有鍵值相等的節點。
其次要注意後續遍歷序列的特點,在後續遍歷得到的序列中,最後一個數字是樹的根節點的值。
以下面的二叉搜索樹爲例:
該二叉搜索樹的後序遍歷序列爲{1,4,3,6,8,7,5}。該序列的最後一個數字5即爲二叉搜索樹的根節點。{1,4,3,6,8,7}爲左子樹和右子樹節點。其中{1,4,3}比5小,是二叉樹的左子樹節點的值,{6,8,7}比5大,是二叉樹的右子樹節點的值。而{1,4,3}的3爲左子根節點,{1,4}爲左子根節點的左右子節點。同理{6,8,7}
因爲要不斷判斷根節點和左右子樹,所以可以採取遞歸的方法,也是最能聯想到的思路。
class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence){
int length = sequence.size();
if(sequence.empty()){
return false;
}
int root = sequence[length-1];
//左子樹
int i=0;
vector<int> leftSequence;
for(i=0;i<length-1;i++){
if(sequence[i]<root){
leftSequence.push_back(sequence[i]);
}
else
break;
}
//右子樹
vector<int> rightSequence;
for(int j=i;i<length-1;j++){
if(sequence[j]>root){
rightSequence.push_back(sequence[j]);
}
else
return false;
}
//判斷左子樹是不是二叉搜索樹
bool left = true;
if(!leftSequence.empty()){
left = VerifySquenceOfBST(leftSequence);
}
//判斷右子樹是不是二叉搜索樹
bool right = true;
if(!rightSequence.empty()){
right = VerifySquenceOfBST(rightSequence);
}
return (left&&right);
}
};
看討論區大神還有更簡潔的代碼實現~~學習一下
class Solution {
bool judge(vector<int> sequence,int l,int r){
if(l>=r)
return true;
int i=r;
while(i>1 && sequence[i-1]>sequence[r]){
i--;
}
for(int j=i-1;j>=1;j--){
if(sequence[j]>sequence[r]){
return false;
}
}
return judge(sequence,l,i-1)&&(judge(sequence,i,r-1));
}
public:
bool VerifySquenceOfBST(vector<int> sequence){
if(!sequence.empty()){
return false;
}
return judge(sequence,0,sequence.size());
}
};
但運行結果有問題,理論應該輸出true的,我的輸出是false,不懂問題出在哪裏啊~~待排