題目描述
輸入一個整數數組,判斷該數組是不是某二叉搜索樹的后序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同。
方法一(遞歸)
后續遍歷得到的序列中最后一個元素一定是樹的根節點的值。數組中前面的數字可以分為兩部分:左子樹的值序列和右子樹的值序列。左子樹值都小於根節點值,右子樹值都大於根節點值。
確定了左子樹值和右子樹值的序列,還是按上面的方法確定對應的子樹的結構,這是一個遞歸的過程。如果遞歸過程中發現其右子序列中有值小於根值,那么這不是一個后序序列。
public boolean VerifySquenceOfBST(int [] sequence) {
if(sequence == null || sequence.length == 0) {
return false;
}
else if(sequence.length == 1) {
return true;
}
return JudgePostOrder(sequence, 0, sequence.length - 1);
}
public boolean JudgePostOrder(int[] sequence, int start, int end) {
if(start >= end) {
return true;
}
int i = start;
while (i <= end && sequence[i] < sequence[end]) {
i++;
}
for (int j = i; j <= end; j++) {
if(sequence[j] < sequence[end]) {
return false;
}
}
return JudgePostOrder(sequence, start, i - 1) && JudgePostOrder(sequence, i, end - 1);
}
方法二(非遞歸)
非遞歸也是一個基於遞歸的思想:
左子樹一定比右子樹小,因此去掉根后,數字分為left,right兩部分,right部分的最后一個數字是右子樹的根,它比左子樹所有值大,因此我們可以每次只看有子樹是否符合條件即可。即使到達了左子樹,左子樹也可以看出由左右子樹組成的樹還像右子樹那樣處理。對於右子樹,左子樹的所有值都比右子樹的根小可以暫時把他看出右子樹的左子樹,只需看看右子樹的右子樹是否符合要求即可。
public boolean VerifySquenceOfBST_2(int [] sequence) {
if(sequence == null || sequence.length == 0) {
return false;
}
else if(sequence.length == 1) {
return true;
}
int size = sequence.length - 1;
int i = 0;
while(size > 0) {
while(sequence[i] < sequence[size]) {
i++;
};
while(sequence[i] > sequence[size]) {
i++;
}
if(i < size) {
return false;
}
i = 0;
size--;
}
return true;
}