题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
题目解析
1、主要意思就是说给你一个序列,你确认下这个序列到底是不是一个二叉搜索树的后序遍历结果;
2、这里稍微讲下,二叉搜索树的概念:根节点为参考,比根节点大的数据在右侧,比根节点小的数据在左侧,叶子节点左子节点比父节点小,右子节点比父节点要大;( 二叉搜索树(BST)又称二叉查找树或二叉排序树。)
解题思路(运用了分治思想、递归思想)
1、了解二叉搜索树的性质:根节点为参考,比根节点大的数据在右侧,比根节点小的数据在左侧,叶子节点左子节点比父节点小,右子节点比父节点要大;;
2、把输入的数组分成三份子集并且三份子集中的每一份的数值都是连续的;(关键处:如何分子集)
3、因为是后序遍历(左小右大;左右根),所以最后一个为根节点(也就是一份);然后从剩下的数值中从头遍历开始,遇到第一个比根节点大的值后,从这个值开始之后要是没有比根结点小的那就对了,否则出错;
4、假设是二叉搜索树,所以根是相对的;因此要不断循环第2,3步骤;
5、判断是否是二叉搜索树;
代码实现
第一种方式:
public class Solution {
public boolean VerifySquenceOfBST(int [] sequence) {
if(sequence == null || sequence.length==0) {
return false;
}
if(sequence.length == 1)
return true;
int endNum = sequence[sequence.length - 1];//根结点
int i = 0;//为了获得第几个数大于根结点
for(; i < sequence.length - 1; i++) {
if(sequence[i] > endNum) {
break;//打破循环
}
}
int index = i;//获取第几个数大于根节点
for(; index < sequence.length - 1; index++) {
//如果有在应该一连串大于根结点的数值里有小于根结点,那就出错了
if(sequence[index] < endNum) {
return false;
}
}
int[] smaller = null;
int[] bigger = null;
smaller = new int[i];//定义小于根结点的子集
bigger = new int[sequence.length- i - 1];//定义大于根结点的子集
int in = 0;
for(int j = 0; j < sequence.length - 1; j ++) {
//把后序遍历的值的数组分别放进两个子集
if(j < i) {
smaller[j] = sequence[j];
} else {
bigger[in ++] = sequence[j];
}
}
if(i == 0) {//若是右子树,那么又来判断右子树中的根结点和其子节点
return VerifySquenceOfBST(bigger);
} else if(i == sequence.length - 1) {//若是左子树
return VerifySquenceOfBST(smaller);
} else {//既是左子树又是右子树
return VerifySquenceOfBST(bigger) && VerifySquenceOfBST(smaller);
}
}
}