二叉搜索树的后序遍历序列
题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。
image
示例:
输入: [1,6,3,2,5]
输出: false
输入: [1,3,2,6,5]
输出: true
提示:
数组长度 <= 1000
题目分析
- 二叉搜索树的特点:
1.1. 左子树的所有节点永远小于等于父节点
1.2. 右子树的所有节点永远大于等于右子树
1.3. 左子树和右子树也是二叉搜索树 - 后续遍历的特点:左子树先遍历、右子树后遍历、父节点最后遍历
举例子: [1,3,2,6,5]
- 根据特点2,根节点显然是5
- 根据特点1.2,我们可以从根节点往前探索,比它大的都是右子树的,剩下的都是左子树的,所以右子树是[6],左子树是[1,3,2]
- 然后对于特点1.1还没有得到验证,所有对于左子树[1,3,2],都必须确保每个元素都比5小,否则不符合二叉搜索树的特点,返回false
- 如果特点1.1得到验证,那么只要证明特点1.3,整棵树就是满足二叉搜索树的特点了,1.3的证明很简单,对左子树和右子树也进行像整棵树一样的操作即可(递归)
public boolean verifyPostorder(int[] postorder) {
if(postorder.length == 1) return true;
return verifyPostorder(postorder,0,postorder.length-1);
}
//验证当前数是否为二叉搜索树
public boolean verifyPostorder(int[] postorder,int head,int tail) {
if(head >= tail) return true;
int parent = postorder[tail];
int rightHead = tail;
//寻找右子树和左子树的分界点
while(rightHead >= head){
if(postorder[rightHead] >= parent)
rightHead--;
else
break;
}
rightHead += 1;
// 验证右子树是否为二叉搜索树
if(!verifyPostorder(postorder,rightHead,tail-1))
return false;
// 验证左子树是否都比父节点小
if(!verifyLeft(postorder,head,rightHead-1,parent))
return false;
// 验证左子树是否为二叉搜索树
return verifyPostorder(postorder,head,rightHead-1);
}
public boolean verifyLeft(int[] postorder,int head,int tail,int parent){
for(int i = head; i <= tail; i++){
if(postorder[i] > parent)
return false;
}
return true;
}
网友评论