//思路一:
//先假设该后续遍历序列可以构成二叉树
//对题目中后序遍历序列进行排序即可获取中序遍历序列
//然后根据中序遍历序列和后序遍历序列构造二叉树
//如果构造失败,返回 false
//如果构造成功,返回 true
public boolean VerifySquenceOfBST(int [] sequence) {
if(sequence==null || sequence.length==0){
return false;
}
int[] post = Arrays.copyOf(sequence,sequence.length);
Arrays.sort(sequence);
TreeNode root = null;
try{
root = reConstrcut(sequence,post,
0,sequence.length-1,0,post.length-1);
}catch (Exception e){ //构造过程中,发生异常,即构造失败
return false;
}
//root==null 也是构造失败
return root!=null;
}
private TreeNode reConstrcut(int[] in,int[] post,
int inStart,int inEnd,int postStart,int postEnd){
if(inStart>inEnd || postStart>postEnd){
return null;
}
TreeNode root = new TreeNode(post[postEnd]);
int index=-1;
for(int i=inStart;i<=inEnd;i++){
if(in[i]==post[postEnd]){
index=i;
break;
}
}
root.left = reConstrcut(in,post,inStart,index-1,
postStart,postStart+(index-inStart-1));
root.right=reConstrcut(in,post,index+1,inEnd,
postStart+(index-inStart),postEnd-1);
return root;
}
//思路二:
//利用二分搜索树性质
//将 sequence 划分为左右子树序列
//如果能构成二分搜索树
//左子树中的数值 <= 根节点值
//右子树中的数值 > 根节点值
public boolean VerifySquenceOfBST(int [] sequence) {
if(sequence==null || sequence.length==0){
return false;
}
return verify(sequence,0,sequence.length-1);
}
private boolean verify(int[] squence,int first,int last){
if(last-first<=1){
//当 last-first==0 时,只有 1 个结点,显然正确
//当 last-first==1 时,只有 2 个结点,此时不管是顺序的还是逆序的都可以构造
return true;
}
int rootVal = squence[last]; //后序遍历最后一个元素值就是根节点的值
int cutIndex = first; // cutIndex 用于切分左右子树
while (cutIndex<last && squence[cutIndex]<=rootVal){ //二分搜索树中左子树所有结点值都小于根节点值
cutIndex++;
}
//左子树 [first,curIndex-1]
//cutIndex 就是右子树的后序遍历的首元素的下标
for(int i=cutIndex;i<last;i++){ //右子树[curIndex,last-1]
if(rootVal>squence[i]){ //右子树中存在大于根节点的值,返回 false
return false;
}
}
return verify(squence,first,cutIndex-1) &&
verify(squence,cutIndex,last-1);
}
www.mianshi.online,www.i9code.cn
本文由博客一文多发平台 OpenWrite 发布!