Loading

树形dp套路

我们知道dp也就是动态规划的思想就是先解决小问题,通过不断的解决小问题,最终解决大问题。那么能够应用树形dp套路的题目都应该符合一个条件,那就是通过解决每个子树的小问题,最终解决整棵树的大问题。

套路

  1. 分析有几种可能
  2. 需要哪些信息
  3. 汇总信息,构造ReturnType
  4. 构造递归函数

找到二叉树中的最大搜索二叉子树

首先,这道题是可以通过先解决小的子树最大搜索二叉子树,然后不断扩大范围,最终解决整棵树的最大搜索二叉子树。

那么分析套路开始:

  1. 分析有哪些情况?

    第一:最大搜索二叉子树在左子树中

    第二:最大搜索二叉子树在右子树中

    第三:整颗左子树+头结点+整颗右子树,是一个搜索二叉树

  2. 需要哪些信息?

    maxBSTHead最大搜索二叉子树的头结点,我们需要返回他

    maxBSTSize最大搜索二叉子树的大小,我们需要跟其他搜索二叉树比较

    左子树的最大值,我们需要这个值跟头结点比较

    右子树的最小值,我们需要这个值跟头结点比较

  3. 合并信息到ReturnType

  4. 构造递归函数

    首先返回值是ReturnType,参数为Node,不多说。终止条件仍然要返回一个ReturnType。对于这种套路都是先左右递归,然后根据各种情况为ReturnType的属性赋值。

/**
 * 找到二叉树中的最大搜索二叉子树
 *
 * @author keboom
 * @date 2021/5/9
 */
public class FindLargestTree {

    class ReturnType {
        public Node maxBSTHead;
        public int maxBSTSize;
        public int min;
        public int max;

        public ReturnType(Node maxBSTHead, int maxBSTSize, int min, int max) {
            this.maxBSTHead = maxBSTHead;
            this.maxBSTSize = maxBSTSize;
            this.min = min;
            this.max = max;
        }
    }


    public ReturnType process(Node X) {
        // base case:如果子树是空树
        if (X == null) {
            return new ReturnType(null, 0, Integer.MAX_VALUE, Integer.MIN_VALUE);
        }
        // 默认直接得到左树全部信息
        ReturnType lData = process(X.left);
        // 默认直接得到右树全部信息
        ReturnType rData = process(X.right);
        // 信息整合
        // 求最小值:X,左子树,右子树
        int min = Math.min(X.value, Math.min(lData.min, rData.min));
        // 求最大值:X,左子树,右子树
        int max = Math.max(X.value, Math.max(lData.max, rData.max));
        // 如果只考虑可能性一和二,也就是最大搜索二叉树是X的左子树或者右子树
        int maxBSTSize = Math.max(lData.maxBSTSize, rData.maxBSTSize);
        // 如果只考虑可能性一和二,也就是最大搜索二叉树是X的左子树或者右子树
        Node maxBSTHead = lData.maxBSTSize >= rData.maxBSTSize ? lData.maxBSTHead : rData.maxBSTHead;
        // 利用收集的信息,可以判断是否存在第三种可能
        if (lData.maxBSTHead == X.left && rData.maxBSTHead == X.right
                && X.value > lData.max && X.value < rData.min) {
            maxBSTSize = lData.maxBSTSize + rData.maxBSTSize + 1;
            maxBSTHead = X;
        }
        return new ReturnType(maxBSTHead, maxBSTSize, min, max);
    }

    public Node getMaxBST(Node head) {
        return process(head).maxBSTHead;
    }

}

判断二叉树是否为平衡二叉树

  1. 有哪些情况?

    就那一种情况,那就是左树,右树都是平衡二叉树,并且高度差小于等于1

  2. 需要哪些信息?

    高度,该树是否为平衡

  3. 综合信息到ReturnType

  4. 构造递归函数

    返回值,参数,终止条件不多说了。同样的格式,先是左右递归,然后操作之。我们需要求ReturnType的属性值,对于树高来说,去左子树和右子树中大的+1即可。对于是否平衡,那么就要求左树和右树都平衡,且高度差小于等于1。

/**
 * @author keboom
 * @date 2021/5/17
 */
public class IsBalanceTree {
    class ReturnType {
        public boolean isBalanced;
        public int height;

        public ReturnType(boolean isBalanced, int height) {
            this.isBalanced = isBalanced;
            this.height = height;
        }
    }

    public boolean isBalanced(Node head) {
        return process(head).isBalanced;
    }

    private ReturnType process(Node head) {
        if (head == null) {
            return new ReturnType(true, 0);
        }
        ReturnType leftData = process(head.left);
        ReturnType rightData = process(head.right);
        int height = Math.max(leftData.height, rightData.height) + 1;
        boolean isBalanced = leftData.isBalanced && rightData.isBalanced
                && Math.abs(leftData.height - rightData.height) < 2;
        return new ReturnType(isBalanced, height);
    }
}

求二叉树中两节点的最大距离

这题要求从一个二叉树中,我找两个距离最远的点,求最远距离是多少?

image-20210521204847654

这棵树找4和6,距离就是最大的5。当然了找4和7,5和6,5和7都是一样的。

image-20210521205144443

打马赛克的是没有了哦😉,比如这颗树,4和5那就是距离最大是为3。当然如果左子树更长一些就好了。

image-20210521205440699

当然还有右子树长一点的。

  1. 有几种情况?

    第一种树比较平衡,那么在左子树,右子树各取一点,那么可能是最大距离

    第二种,左子树比较长,右子树比较短,那么从左子树中去两点,可能是最大距离

    第三种,右子树长,左子树短,则从右子树取两点

  2. 需要哪些信息?

    树高,用来计算两点的距离

    最长距离,需要进行比较

  3. 放到ReturnType

  4. 构造递归函数

    只说maxDistance,那就是三种情况中取最大的。

    public class ReturnType {
        public int maxDistance;
        public int height;

        public ReturnType(int maxDistance, int height) {
            this.maxDistance = maxDistance;
            this.height = height;
        }
    }

    public int getMaxDistance(Node head) {
        return process(head).maxDistance;
    }

    private ReturnType process(Node head) {
        if (head == null) {
            return new ReturnType(0, 0);
        }
        ReturnType leftData = process(head.left);
        ReturnType rightData = process(head.right);
        int height = Math.max(leftData.height, rightData.height) + 1;
        int maxDistance = Math.max(leftData.height + rightData.height + 1,
                Math.max(leftData.maxDistance, rightData.maxDistance));
        return new ReturnType(maxDistance, height);
    }
posted @ 2021-05-21 21:03  KeBoom  阅读(93)  评论(0编辑  收藏  举报