【二叉树】最大的二叉搜索子树的大小

给定一棵二叉树的头节点head,
返回这颗二叉树中最大的二叉搜索子树的大小

方法1:

    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }
    public static int 最大的二叉搜索子树的大小(Node head) {
        if (head == null) {
            return 0;
        }
        return process(head).maxBinarySearchSize;
    }

    public static class Info {
        private int minVal;
        private int maxVal;
        private int maxBinarySearchSize;
        private boolean isBinarySearch;

        public Info(int min, int max, int mbss, boolean ibss) {
            minVal = min;
            maxVal = max;
            maxBinarySearchSize = mbss;
            isBinarySearch = ibss;
        }
    }

    public static Info process(Node x) {
        if (x == null) {
            return null;
        }

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

        int minVal = x.value;
        int maxVal = x.value;
        int maxBinarySearchSize = 1;
        boolean isBinarySearch = true;

        if (leftInfo != null) {
            minVal = Math.min(minVal, leftInfo.minVal);
            maxVal = Math.max(maxVal, leftInfo.maxVal);
            isBinarySearch = isBinarySearch && leftInfo.isBinarySearch;
            if (leftInfo.maxVal >= x.value) {
                isBinarySearch = false;
            }
        }
        if (rightInfo != null) {
            minVal = Math.min(minVal, rightInfo.minVal);
            maxVal = Math.max(maxVal, rightInfo.maxVal);
            isBinarySearch = isBinarySearch && rightInfo.isBinarySearch;
            if (rightInfo.minVal <= x.value) {
                isBinarySearch = false;
            }
        }
        if ((leftInfo != null && rightInfo != null)) {
            if (leftInfo.isBinarySearch && rightInfo.isBinarySearch && leftInfo.maxVal < x.value && rightInfo.minVal > x.value) {
            //如果左右子树都存在
            //如果当前节点左右子树都是BST,并且当前节点的树和左右子树也符合BST
            //那么最大BST大小是 左+右+1
                maxBinarySearchSize = leftInfo.maxBinarySearchSize + rightInfo.maxBinarySearchSize + 1;
            } else {
            //如果左或右子树不是BST 或者 当前节点的树和左右节点不符合BST
            //那么最大BST大小是 左右子树中较大BST的大小
                maxBinarySearchSize = Math.max(leftInfo.maxBinarySearchSize, rightInfo.maxBinarySearchSize);
            }
        }
        if (leftInfo != null && rightInfo == null) {
            if (leftInfo.isBinarySearch && leftInfo.maxVal < x.value) {
            //如果只有左子树 右子树为空
            //并且左子树是BST, 当前节点的树跟左子树也符合BST
            //那么最大BST大小是 左子树最大BST大小+1
                maxBinarySearchSize = leftInfo.maxBinarySearchSize + 1;
            } else {
            //如果左子树不是BST 或者 当前节点的树和左子树不符合BST
            //那么最大BST大小是 左子树最大BST大小
                maxBinarySearchSize = leftInfo.maxBinarySearchSize;
            }
        }
        if (leftInfo == null && rightInfo != null) {
            if (rightInfo.isBinarySearch && rightInfo.minVal > x.value) {
                maxBinarySearchSize = rightInfo.maxBinarySearchSize + 1;
            } else {
                maxBinarySearchSize = rightInfo.maxBinarySearchSize;
            }
        }
        return new Info(minVal, maxVal, maxBinarySearchSize, isBinarySearch);
    }

方法2:
tips : 二叉搜索树中序遍历的结果是升序

    public static int getBSTSize(Node head) {
        ArrayList<Node> arr = new ArrayList<Node>();
        in(head, arr);

        int size = arr.size();
        for (int i = 1; i < arr.size(); i++) {
            if (arr.get(i).value <= arr.get(i - 1).value){
                return 0;
            }
        }

        return size;
    }

    public static void in(Node head, ArrayList<Node> arr) {
        if (head == null) {
            return;
        }
        in(head.left, arr);
        arr.add(head);
        in(head.right, arr);
    }

    public static int maxSubBSTSize1(Node head) {
        if (head == null) {
            return 0;
        }
        int bstSize = getBSTSize(head);
        if (bstSize != 0){
            return bstSize;
        }

        return Math.max(maxSubBSTSize1(head.left),maxSubBSTSize1(head.right));
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值