题解 | #二叉搜索树的后序遍历序列#
二叉搜索树的后序遍历序列
http://www.nowcoder.com/practice/a861533d45854474ac791d90e447bafd
我的想法比较直白简单,但是代码就相对复杂了:
1、对于二叉搜索树,主要的特性就是,节点的左边的所有节点一定比当前节点值小,节点右边的一定比当前的节点值大;
2、后序遍历出来的序列,主要特征就是该序列的最后一个值一定是改树的根节点。
根据以上两点就可以很好的判断出,整个序列哪一些是左子树,哪一些是右子树,因为比根节点小全都应该在左边,比根节点到的都应该在右边,如果违背了这个规则那么就说明不符合题目要求,返回false。
当判断了整改序列之后发现没有问题,那就还得分别判断左子树,和右子树。同样也可以当做一个完整的树来判断,这里就使用递归就OK了,直到最后,发现全部子序列都符合这个规则,那就说明这个序列符合要求,返回true。
public boolean VerifySquenceOfBST(int [] sequence) {
if(sequence.length == 1)return true;//如果一开始该序列就是只有一个数据,一定符合要求
if(sequence.length == 0)return false;//同理一开始空序列,一定不符合要求
Solution jz = new solution();
int length = sequence.length;
int root = sequence[length-1];//根节点
ArrayList<Integer> left = new ArrayList<Integer>();
ArrayList<Integer> right = new ArrayList<Integer>();
boolean flag = false;//flag 的作用就是在循环判断序列时,当遇到了第一个比root大的值时变为true,也就是说从这里开始后面的序列都是右子树,这些值都要大于root,如果出现了不大于的情况就说明不符合要求。
for (int i = 0 ; i < length ; i++){
if(!flag && sequence[i] > root ){
flag = true;
}
if(flag && sequence[i] < root ){
return false;
}
if ( sequence[i] < root ){//保存左子树序列,由于不知道长度,使用list,递归前将他们转换回数组即可
left.add(sequence[i]);
}
if ( sequence[i] > root && i < length-1){//保存右子树序列
right.add(sequence[i]);
}
}
int arrLeft[] = jz.change(left);//左子树List转换成数组
int arrRight[] = jz.change(right);//同上
boolean result = false;
if (arrLeft == null || arrLeft.length < 2){//这里判断数组的长度之后在去递归,如果子序列的长度小于2 那么该子序列没必要去递归判断了,一定符合要求。-------(1)
result = true;
}else if ( VerifySquenceOfBST( arrLeft ) ){//递归判断左子序列
result = true;
}
if(result && (arrRight == null || arrRight.length <2) ){//在左子树符合要求的前提先下再去判断右子树的长度,同上面(1)
result = true;
}else if ( result && !VerifySquenceOfBST( arrRight ) ){//递归判断右子序列
result = false;
}
return result;
}
public int[] change(ArrayList list){//将list转换成数组
int length = list.size();
int array[] = new int[length];
for (int i = 0; i < length; i++){
array[i] =(int)list.get(i);
}
return array;
}
美的集团公司福利 767人发布