最大的子搜索二叉树的大小 树型DP

最大的子搜索二叉树的大小 树型DP

代码和注释原理如下:

package beginner.tree;

/**
 * 最大的子搜索二叉树的大小
 * Dynamic Programming
 *
 * @Auther: 苏察哈尔丶灿
 * @Date: 2020/9/27 16:25
 * @Slogan: 我自横刀向天笑,笑完我就去睡觉。
 */
public class MaxSubSBTSize {

    // 需要向子树寻求的信息
    private class Info {
        // 子数的最大搜索二叉树值
        public int subBSTSize;
        // 是不是搜索二叉树
        public boolean isBST;
        // 最小值
        public int min;
        // 最大值
        public int max;

        public Info(int subBSTSize, boolean isBST, int min, int max) {
            this.subBSTSize = subBSTSize;
            this.isBST = isBST;
            this.min = min;
            this.max = max;
        }
    }

    public Info process(Node node) {

        // 和 【当前node】 无关
        // 我的最大二叉搜索子树大小是我左右儿子的最大值


        // 和 【当前node】 有关
        //  我的左子树是不是搜索二叉树
        //  我的右子树是不是搜索二叉树
        //  我是不是搜索二叉树   左最大值 < 我的值 < 右最小值

        if (node == null) {
            // 不好判断他的info属性 那就甩锅给上层
            // 上层要做好判空
            return null;
        }

        Info leftInfo = process(node.left);
        Info rightInfo = process(node.right);

        int min = node.value;
        int max = node.value;
        if (leftInfo != null) {
            min = Math.min(min, leftInfo.min);
            max = Math.max(max, leftInfo.max);
        }
        if (rightInfo != null) {
            min = Math.min(min, rightInfo.min);
            max = Math.max(max, rightInfo.max);
        }
        // 至此 所需要的两个参数获取完成

        // 是不是搜索二叉树
        boolean isBST = false;

        // 可能空指针
        // int subBSTSize = Math.max(leftInfo.subBSTSize, rightInfo.subBSTSize);
        int subBSTSize = 0;
        if (leftInfo != null) {
            // 和0比max 还不如直接替换
            subBSTSize = leftInfo.subBSTSize;
        }
        if (rightInfo != null) {
            // 和0比max 还不如直接替换
            // 但是可能上面逻辑已经给赋值过了 所以这一步替换值有风险  需要判断
            subBSTSize = Math.max(subBSTSize, rightInfo.subBSTSize);
        }

        // 前提条件 空节点默认成立搜索树
        if (
            // 左子树是
                (leftInfo == null ? true : leftInfo.isBST)
                        &&
                        // 右子树是
                        (rightInfo == null ? true : rightInfo.isBST)
                        &&
                        // 左大值<我<右小值
                        (leftInfo == null ? true : leftInfo.max < node.value)
                        &&
                        (rightInfo == null ? true : rightInfo.min > node.value)
        ) {
            // 标记是搜索二叉树
            isBST = true;

            // 我的左右子树都是搜索二叉树了 那么树大小就全等于 两个子树身上搜索二叉树size属性的的大小了
            // 我的最大大小就是他们最大的 + 1
            subBSTSize = (leftInfo == null ? 0 : leftInfo.max) + (rightInfo == null ? 0 : rightInfo.max) + 1;
        }


        // 返回info
        return new Info(subBSTSize, isBST, min, max);
    }

    public static void main(String[] args) {
        MaxSubSBTSize maxSubSBTSize = new MaxSubSBTSize();
        Node head = new Node();// 假设这是一个二叉树头节点引用,补齐懒得写
        Info processInfo = maxSubSBTSize.process(head);
        System.out.println(processInfo.subBSTSize);// 当前节点搜索二叉子树的最大大小
    }
}

// 二叉树节点类型
class Node {
    int value;
    Node left;
    Node right;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值