题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
思路
- 找到根结点;
- 找到左右子树:遍历序列,找到第一个大于等于根结点的元素i,则i左侧为左子树、i右侧为右子树;(比如图上的二叉搜索树,后续遍历的结果是[1,6,10,12,9,17,25,18,16],root是16,左边部分是[1,6,10,12,9],右边部分是[17,25,18])
- 已经知道i左侧所有元素均小于根结点,所以依次遍历右侧,看是否所有元素均大于根结点;若出现小于根结点的元素,则直接返回false;若右侧全都大于根结点,则
- 分别递归判断左子树序列和右子树序列是不是二叉搜索树的的后序遍历序列;
实现
public class Solution {
public boolean VerifySquenceOfBST(int[] sequence) {
if (sequence == null || sequence.length == 0)
return false;
return helper(sequence, 0, sequence.length - 1);
}
boolean helper(int[] sequence, int start, int end) {
//start =end 子树中只有一个元素,即到达叶子节点
//start >end 只有右子树没有左孩子的树
if (start >= end)
return true;
// 当前数组(从start到end部分)的根节点
int root = sequence[end];
int i;
//找到左子树和右子树的分界 :左子树都比根节点的值小
// i为右子树的开始结点
for (i = start; i < end; ++i)
if (sequence[i] > root)
break;
//判断右子树 :右子树都比根节点的值大 若小于根节点的值,返回false
for (int j = i; j < end; ++j)
if (sequence[j] < root)
return false;
//递归判断左子树序列和右子树序列是不是二叉搜索树的的后序遍历序列
return helper(sequence, start, i - 1) && helper(sequence, i, end - 1);
}
}
解释递归结束的条件
if (start >= end)
return true;
start =end 子树中只有一个元素,即到达叶子节点
start >end 只有右子树没有左孩子的树
扩展
扩展:
输入一个数组,判断该数组是不是某二叉搜索树的前序遍历的结果。
思路:
这其实和上面的二叉搜索树的后序遍历规律是一样的,不过后序遍历根结点在后面,前序遍历根结点在前面而已,即第一个就是根结点的值。
//https://blog.youkuaiyun.com/u013132035/article/details/80607000
```java
public class VerifySquenceOfBSTSolution_kuozhan {
public boolean verifySquenceOfBST(int sequence[]){
if(sequence == null){
return false;
}
return verifySquenceOfBST1(sequence, 0, sequence.length - 1);
}
private boolean verifySquenceOfBST1(int[] sequence, int start, int end) {
if(start < end){
return false;
}
int root = sequence[start]; //后序遍历的最后一个结点为根结点
//在二叉搜索树中左子树的结点小于根结点
int i = 1;
for(; i < end; ++i){
if(sequence[i] > root){
break;
}
}
//在二叉搜索树中右子树的结点大于根结点
int j = i;
for(; j < end; ++j){
if(sequence[j] < root){
return false;
}
}
//判断左子树是不是二叉树
boolean left = true;
if(i > start+1){
left = verifySquenceOfBST1(sequence, start+1, i-1);
}
//判断右子树是不是二叉树
boolean right = true;
if(i < end){
right = verifySquenceOfBST1(sequence, i, end);
}
return (left && right);
}
}