题目
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
分析
思路一:
二叉搜索树:root.left.val < root.val < root.right.val
后序遍历:先左后右最后根。
先找出根节点即为序列的最后一个数,通过从头开始比较与根节点的值,小于则是左子树,大于的话其后的所有数都为右子树部分。这样就找出了左子树和右子树的分界点,我们可以保证该分界点左侧一定是小于根节点的值的,即左侧全为左子树。只需要比较右侧的值是否可以保证大于根节点的值呢?然后递归再分别比较其左子树和右子树的子序列是否都符合二叉搜索树的后序遍历规则,也即调用自身。
时间复杂度:o(N)
空间复杂度:o(N)
代码:
public class Solution {
public boolean VerifySquenceOfBST(int [] sequence) {
if(sequence==null||sequence.length<=0) return false;
return VerifySquenceOfBST(sequence, 0, sequence.length-1);
}
private boolean VerifySquenceOfBST(int [] sequence,int start,int end) {
//如果遍历完序列仍然没出错就返回true
if(start>=end) return true;
//根结点
int root = sequence[end];
//寻找左右子树的分界点
int i=0;
//此处i<end是因为如果当只有右节点时,若再执行下面的递归判断左子节点时会越界
while(sequence[i]<=root && i<end) i++;
//判断右子树是否有大于根节点的节点
int j=i;
while(j<end){
if(sequence[j]<root) return false;
j++;
}
//如果上述都满足则继续递归分别检查其左子树和右子树是否为后序序列
boolean left = VerifySquenceOfBST(sequence,start,i-1);
boolean right = VerifySquenceOfBST(sequence,i,end-1);
return left&&right;
}
}