题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出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;
}