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

给定一棵二叉树的头节点head,已知其中所有节点的值都不一样,找到含有节点最多的搜索二叉树,并返回这颗子树的数量。

分析答案的可能性

  • 第一种:X为头节点的子树中,最大的搜索二叉树就是X的左子树中的最大搜索二叉子树。即答案来自左子树
  • 第二种:X为头节点的子树中,最大的搜索二叉树就是X的右子树中的最大搜索二叉子树。即答案来自右子树
  • 第三种:若X左子树上的最大搜索二叉子树是X左子树的全体,X右子树上的最大搜索二叉子树是X右数全体,并且X的值大于X的左子树所有节点的最大值,且小于X右子树所有节点的最小值,那么X为头节点的子树中,最大的搜索二叉子树是以X为头节点的全体。
  • public static int largestBSTSubtree(TreeNode head) {
            if (head == null) {
                return 0;
            }
            return process(head).maxBSTSubtreeSize;
        }
    
        public static class Info {
            public int maxBSTSubtreeSize;
            public int allSize;
            public int max;
            public int min;
    
            public Info(int m, int a, int ma, int mi) {
                maxBSTSubtreeSize = m;
                allSize = a;
                max = ma;
                min = mi;
            }
        }
    
        public static Info process(TreeNode x) {
            if (x == null) {
                return null;
            }
            Info leftInfo = process(x.left);
            Info rightInfo = process(x.right);
            int max = x.val;
            int min = x.val;
            int allSize = 1;
            if (leftInfo != null) {
                max = Math.max(leftInfo.max, max);
                min = Math.min(leftInfo.min, min);
                allSize += leftInfo.allSize;
            }
            if (rightInfo != null) {
                max = Math.max(rightInfo.max, max);
                min = Math.min(rightInfo.min, min);
                allSize += rightInfo.allSize;
            }
            int p1 = -1;
            if (leftInfo != null) {
                p1 = leftInfo.maxBSTSubtreeSize;
            }
            int p2 = -1;
            if (rightInfo != null) {
                p2 = rightInfo.maxBSTSubtreeSize;
            }
            int p3 = -1;
            boolean leftBST = leftInfo == null ? true : (leftInfo.maxBSTSubtreeSize == leftInfo.allSize);
            boolean rightBST = rightInfo == null ? true : (rightInfo.maxBSTSubtreeSize == rightInfo.allSize);
            if (leftBST && rightBST) {
                boolean leftMaxLessX = leftInfo == null ? true : (leftInfo.max < x.val);
                boolean rightMinMoreX = rightInfo == null ? true : (x.val < rightInfo.min);
                if (leftMaxLessX && rightMinMoreX) {
                    int leftSize = leftInfo == null ? 0 : leftInfo.allSize;
                    int rightSize = rightInfo == null ? 0 : rightInfo.allSize;
                    p3 = leftSize + rightSize + 1;
                }
            }
            return new Info(Math.max(p1, Math.max(p2, p3)), allSize, max, min);
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值