題目描述:
輸入一個整數數組,判斷該數組是不是某二叉搜索樹的后序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同。
解題思路:
對於后續遍歷序列,序列的最后一個值一定是樹的根結點,而由二叉搜索樹的性質:左小右大,我們可以從頭開始遍歷,當遍歷到某個值比根結點大時停止,記為flag,此時flag之前的所有數值都是二叉搜索樹的左子樹的結點,flag以及flag之后的所有數都是二叉搜索樹的右子樹的結點。這是由二叉搜索樹以及后序遍歷共同決定的。
接下來,我們就可以把任務交給遞歸,同樣的方法去判斷左子樹和右子樹是否是二叉搜索樹,這顯然是典型的遞歸解法。
舉例:
以{5,7,6,9,11,10,8}為例,后序遍歷結果的最后一個數字8就是根結點的值。在這個數組中,前3個數字5、7和6都比8小,是值為8的結點的左子樹結點;后3個數字9、11和10都比8大,是值為8的結點的右子樹結點。
我們接下來用同樣的方法確定與數組每一部分對應的子樹的結構。這其實就是一個遞歸的過程。對於序列5、7、6,最后一個數字6是左子樹的根結點的值。數字5比6小,是值為6的結點的左子結點,而7則是它的右子結點。同樣,在序列9、11、10中,最后一個數字10是右子樹的根結點,數字9比10小,是值為10的結點的左子結點,而11則是它的右子結點,所以它對應的二叉搜索樹如下:
編程實現(Java):
public class Solution {
public boolean VerifySquenceOfBST(int [] sequence) {
if(sequence==null||sequence.length==0)
return false;
return VerifySquenceOfBST(sequence,0,sequence.length-1);
}
public boolean VerifySquenceOfBST(int [] sequence,int begin,int end){
if(end<=begin) //結束條件
return true;
//end為根節點,找左右子樹的分界
int i=begin;
for(;i<end;i++) //找邊界,並同時判斷了左子樹都小於根
if(sequence[i]>sequence[end])
break;
for(int j=i+1;j<end;j++) //右子樹如果存在小於根的,則不是二叉搜索樹
if(sequence[j]<sequence[end])
return false;
return VerifySquenceOfBST(sequence,begin,i-1) && VerifySquenceOfBST(sequence,i,end-1);
}
}
