二叉树的递归套路(适用于树形dp)

判断搜索二叉树

 public static class Info {
   // 需要从子树获取什么信息?
   // 子树是否是搜索二叉树
   // 子树的最大值
   // 子树的最小值
        boolean isBST;
        int max;
        int min;
        Info(boolean isBST, int max, int min) {
            this.isBST = isBST;
            this.max = max;
            this.min = min;
        }
    }
    
    public Info recur(TreeNode root) {
        if(root == null) {
            return null;
        }
      //获取子树信息
        Info leftInfo = recur(root.left);
        Info rightInfo = recur(root.right);
        
      //设置根信息
        int min = root.val, max = root.val;
        if(leftInfo != null)
            min = Math.min(min, leftInfo.min);
        if(rightInfo != null)
            max = Math.max(max, rightInfo.max);
      // 子树都是搜索二叉树
      // 左子树的最大值小于root
      // 右子树的最小值大于root
        boolean isBST = (leftInfo == null ? true : (leftInfo.max < root.val) && (leftInfo.isBST))
            &&
                (rightInfo == null ? true : (rightInfo.min > root.val) && (rightInfo.isBST));
        return new Info(isBST, max, min);
    }

判断满二叉树

判断平衡二叉树

public class Solution {
    public static class Info {
   // 需要从子树获取什么信息?
   // 子树是否是平衡二叉树
   // 子树的高度
        boolean isBT;
        int height;
        Info(boolean isBT, int height) {
            this.isBT = isBT;
            this.height = height;
        }
    }
    public Info recur(TreeNode root) {
        if(root == null)
            return new Info(true, 0);
      // 获取子树信息
        Info leftInfo = recur(root.left);
        Info rightInfo = recur(root.right);
      // 设置根信息
        int height = Math.max(leftInfo.height, rightInfo.height) + 1;
      // 子树都是平衡二叉树
      // 子树的高度差不超过 1
        boolean isBT = leftInfo.isBT && rightInfo.isBT && Math.abs(leftInfo.height - rightInfo.height) < 2;
        return new Info(isBT, height);
    }
    public boolean IsBalanced_Solution(TreeNode root) {
        return recur(root).isBT;
    }
}

最近公共祖先

public class Solution {
    public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
        return recur(root, o1, o2).ancestor.val;
    }
    public static class Info {
   // 需要从子树获取什么信息?
   // 是否找到o1
   // 是否找到o2
   // 是否找到最近公共祖先
        boolean findO1;
        boolean findO2;
        TreeNode ancestor;
        Info(boolean findO1, boolean findO2, TreeNode ancestor) {
            this.findO1 = findO1;
            this.findO2 = findO2;
            this.ancestor = ancestor;
        }
    }
    
    public Info recur(TreeNode root, int o1, int o2) {
        if(root == null)
            return new Info(false, false, null);
      // 获取子树的信息
        Info leftInfo = recur(root.left, o1, o2);
        Info rightInfo = recur(root.right, o1, o2);
      // 如果已经找到了祖先 直接返回
        if(leftInfo.ancestor != null)
            return new Info(false, false, leftInfo.ancestor); 
        if(rightInfo.ancestor != null)
            return new Info(false, false, rightInfo.ancestor); 
      // 如果此时一个子树找到了o1, 另一个子树找到了o2 那么根就是他们的最近公共祖先
        if(leftInfo.findO1 && rightInfo.findO2 || leftInfo.findO2 && rightInfo.findO1)
            return new Info(true, true, root); 
      // 设置信息
        boolean findO1 = root.val == o1;
        boolean findO2 = root.val == o2;
      // 找到了o1 而根是o2 或者 找到了o2 而根是o1 那么根就是他们的最近公共祖先
        if((leftInfo.findO1 || rightInfo.findO1) && findO2 ||(leftInfo.findO2 || rightInfo.findO2) && findO1)
            return new Info(true, true, root); 
      // 返回已有的信息
        return new Info((leftInfo.findO1 || rightInfo.findO1) || findO1, (leftInfo.findO2 || rightInfo.findO2) || findO2, null);
            
    }
}
posted @ 2022-02-10 23:04  brbrbr  阅读(44)  评论(0)    收藏  举报