【LeetCode(Java) - 333】最大 BST 子树

1、题目描述

在这里插入图片描述

2、解题思路

  本题有两个问题:找出二叉树中的为 BST 的子树,返回最大的那个 BST 子树的节点数。

  因此,必须从叶子节点往根节点的方向遍历,即 DFS。

  对于叶子节点来说,它本身就是一颗 BST,节点数为 1。

  对于非叶子节 node 点来说,有以下情况:

  1、左右子节点为根节点的子树均为 BST,且 node 大于左子树的最大值,小于右子树的最小值,于是以 node 为根节点的树也是 BST,于是又找到一颗更大的 BST,节点数为左右子树结点数之和加一。

  2、当前节点 node 不满足构成 BST 的条件,于是只能从左右子树中找最大 BST。

  可以定义一个类来存储每个 BST 根节点的信息。

  具体实现看代码。

3、解题代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    
    

    class Result {
    
    
        TreeNode node; // BST根节点
        int size; // BST的size
        int max; // BST的最大值
        int min; // BST的最小值
    }

    public int largestBSTSubtree(TreeNode root) {
    
    
        Result r = dfs(root);
        return r == null ? 0 : r.size;
    }

    public Result dfs(TreeNode node) {
    
    
        if (node == null) return null;

        Result l = null, r = null;
        if (node.left != null) l = dfs(node.left);
        if (node.right != null) r = dfs(node.right);

        // 当前树为BST
        boolean lValid = (l == null || (l.node == node.left && l.max < node.val));
        boolean rValid = (r == null || (r.node == node.right && r.min > node.val));
        if (lValid && rValid) {
    
    
            Result result = new Result();
            result.node = node;
            result.max = r == null ? node.val : r.max;
            result.min = l == null ? node.val : l.min;
            result.size = (l == null ? 0 : l.size) + (r == null ? 0 : r.size) + 1;
            return result;
        }

        // 左右子树中找到了BST
        if (l != null && r != null) {
    
    
            return l.size > r.size ? l : r;
        }
        if (l != null) return l;
        if (r != null) return r;

        return null;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_29051413/article/details/108530837