《剑指Offer》Java刷题 NO.23 二叉树的后序遍历序列

《剑指Offer》Java刷题 NO.23 二叉树的后序遍历序列(二叉搜索树、后序遍历、二分查找、递归)

时间:2020-02-29 题目: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。


思路: 先明确什么是二叉搜索树: 根节点的值大于其左子树中任意一个节点的值,小于其右节点中任意一节点的值,这一规则适用于二叉搜索树中的每一个节点;也就是说左子树的所有值<根结点的值<右子树的所有值,适用于所有的子树。例如下图: 后序遍历输出应该为:3 4 9 5 12 11 10

  1. 既然所有的子树都要满足以上规则,那么递归方法是很合适的,观察可以发现树的根结点放在数组的最右端
    从头开始找到第一个大于根结点的结点作为分界 然后判断当前节点开始到倒数第二个结点,如果有结点的值比根节点的值小的话,就返回false,否则就继续递归判断左子树和右子树是否同时为true 递归的结束条件是入参子数组的长度<=2,此时应该直接返回true,两个元素,例如上图的[3,4]子树,不论顺序是[3,4]还是[4,3]都可以被认为是后序遍历; 另外,当子数组长度为3时,不用再进行对左右子树的递归了,直接在循环判断结束之后返回结果就行了,因为此时左右子树都只有一个元素。
  1. 大神写的一个非递归程序,虽然复杂度有点高,是O(n²),但是思路很好 因为右子树的根节点的值依旧大于上一层的左子树和本身的左子树,所以每次把size减一,从右向左判断每一个结点对应的剩余子树节点顺序是不是符合规则; 判断规则为从第一个结点开始找到第一个大于根结点(当前最后元素)的结点,然后继续从当前结点往后找直到结点的值不大于根结点,判断是否正好到了倒数第二个结点,如果不是就返回false

Java代码:

/**
 * 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。
 * 假设输入的数组的任意两个数字都互不相同。
 */
public class VerifySequenceOfBST {
          
   
    public static boolean verifySequenceOfBST1(int[] sequence){
          
   
        if(sequence.length == 0) return false;
        return judge(sequence,0,sequence.length-1);
    }
    public static boolean judge(int[] arr,int start,int root){
          
   
        int length = root-start+1;
        if(length <= 2) return true;
        int i = 0;
        for(;i < root;i++){
          
   
            if(arr[i] > arr[root]) break;
        }
        int j=i-1;
        for(;i < root;i++){
          
   
            if(arr[i] < arr[root]) return false;
        }
        if(length==3) return true;
        return judge(arr,start,j)&&judge(arr,j+1,root-1);
    }

    /**
     *非递归解法
     */
    public static boolean verifySequenceOfBST2(int[] sequence){
          
   
        int size=sequence.length;
        if(size==0) return false;
        if(size<=2) return true;
        while(--size>=0){
          
   
            int i=0;
            while (sequence[i]<sequence[size]) i++;
            while (sequence[i]>sequence[size]) i++;
            if(i!=size) return false;
        }
        return true;
    }
    public static void main(String[] args) {
          
   
        int[] test0={
          
   1};
        int[] test1={
          
   3,4};
        int[] test2={
          
   1,2,3};
        int[] test3={
          
   1,3,2};
        int[] test4={
          
   3,8,5,11,14,13,10};
        System.out.println(verifySequenceOfBST2(test1));
    }
}
经验分享 程序员 微信小程序 职场和发展