题目
输入一个整数数组,判断该数组是不是某个二叉搜索树的后续遍历结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。
示例
5
/ \
2 6
/ \
1 3
输入: [1,6,3,2,5]
输出: false
输入: [1,3,2,6,5]
输出: true
解题思路
在后序遍历得到的序列中,最后一个数字是树的根节点,对于BST二叉搜索树来讲,左子树上的元素都小于根节点,右子树的元素都大于根节点。所以从左到右遍历数组,直到遇到第一个大于根节点的数字break,之前的数字是根节点的左子树的元素,剩下的是右子树中的元素。如果右子树中包含有小于根节点的元素代表这个序列不是根节点的后续遍历序列,直接返回false。
根据以上规则,递归左子树和右子树,依次判断序列是否合法。如果左右子树都合法,返回true。
举例:{7,4,6,5}
这个数组中的最后一个元素是5,但是第一个元素是7,大于5,表示这棵树没有左子树,遍历到第二个元素4,因为4<5,这就违背了二叉搜索树的定义,因此直接返回false。
编码实现
public boolean verifyPostorder(int[] postorder) {
//空树或者是只有根节点返回true
if(postorder==null||postorder.length<2) return true;
int N = postorder.length;
return verifyHelp(postorder,0,N-1);
}
public boolean verifyHelp(int[] arrays,int start,int end){
if(start>=end) return true;
//最后一个元素是根节点
int root = arrays[end];
int i=start;
for (;i<end;i++){
//根节点的左子树中的元素都小于根节点,如果大于代表是右子树的开始
if (arrays[i]>root) break;
}
for (int j=i;j<end;j++){
//如果右子树中的元素有小于根节点,直接返回false
if (arrays[j]<root) return false;
}
//验证左子树是否合法(start,i-1),验证右子树是否合法(i,end)
return verifyHelp(arrays,start,i-1)&&verifyHelp(arrays,i,end-1);
}