Largest BST SubTree

113 阅读1分钟

题目

给定一个二叉树,返回其包含的最大(节点数量最多)二叉搜索树的大小

输入: root = [10,5,15,1,8,null,7]
输出: 3
解释: 本例中最大的 BST 子树是高亮显示的子树。返回值是子树的大小,即 3 。

解法

  1. Brute Force 遍历该树,对每个节点判断其树是否是二叉搜索树(以该节点为根节点的树),时间复杂度为O(N2)
  2. 树的动态规划:使用后序遍历,某节点node是二叉搜索树的条件为其左子树,右子树均为二叉搜索树,且node.val > max({left node vals}) 且 node.val < min({right node vals}),只用O(N)就能完成

注意

因为二叉搜索树是左<中<右,所以在返回Node的时候,min只需要在左子树里面找最小的,max只用在右子树里找最大的。

class Solution {
    int res = 0;;
    class Node {
        int min;
        int max;
        int size;
        public Node(int min, int max, int validSize) {
            this.min = min;
            this.max = max;
            this.size = validSize;
        }
    }

    public int largestBSTSubtree(TreeNode root) {
        if (root == null) {
            return 0;
        }
        dfs(root);
        return res;
    }

    public Node dfs(TreeNode node) {
        Node left = null, right = null;
       if (node.left != null) {
           left = dfs(node.left);
       }

       if (node.right != null) {
           right = dfs(node.right);
       }

       int min = node.val;
       int max = node.val;
       boolean valid = true;
       int size = 1;


       if (left != null) {
           min = left.min;
           if (left.size >= 0 && node.val > left.max) {
               size += left.size;
           } else {
               valid = false;
           }
       }

       if (right != null) {
           max = right.max;
           if (right.size >= 0 && node.val < right.min) {
               size += right.size;
           } else {
               valid = false;
           }
       }

       if (valid) {
           res = Math.max(res, size);
           return new Node(min, max, size);
       } else {
           return new Node(-1, -1, -1);
       }
    }
}