思路:二叉搜索树的特点:左孩子比根节点小,右孩子比根节点大。
而后续遍历的特点是:先遍历左子树,再遍历右子树,再遍历根。
所以根据二叉搜索树和后序遍历的特点,我们就能发现,根节点一定是最后一个元素。从头向后找第一个比根节点大的元素之前,是左子树,而找到的那个元素之后一直到根节点之前是右子树。
第一步:找到根节点。也就是最后一个下标对应的值。
第二步:找到右子树的第一个值,从前向后找到第一个比根节点大的数字此数字就是右子树的前界,后界为根节点的前一个。而左子树为此数字的之前的序列。
第三步:递归,将序列的下标给定再次判断根节点和左子树和右子树的大小关系。一直到没有左右子树为止,判断当前子树是否为正确的二叉搜索树,如果是,那么就是true,返回至上一层。如果不是返回false。
public static boolean verifyPostorder(int[] postorder) {
if(postorder == null || postorder.length == 0) return true;
return verifyPostorder(postorder,0,postorder.length-1);
}
private static boolean verifyPostorder(int[] postorder, int begin, int end){
//证明此时没有树
if(begin >= end) return true;
int currentRoot = postorder[end];
int rightBegin = begin;
for( ; rightBegin < end ;rightBegin++){
if(postorder[rightBegin] > currentRoot) break;
}
//检查左子树和右子树的合法性。
for(int i = rightBegin;i <= end-1;i++){
if(postorder[i] < currentRoot) return false;
}
return verifyPostorder(postorder,begin,rightBegin-1) && verifyPostorder(postorder,rightBegin,end-1);
}