📌  相关文章
📜  在给定的二叉树中找到最大的BST子树|套装1(1)

📅  最后修改于: 2023-12-03 15:23:37.095000             🧑  作者: Mango

在给定的二叉树中找到最大的BST子树|套装1

题目描述

给定一个二叉树,找到其中最大的BST子树。其中最大指的是子树节点数最多的BST子树。子树必须包含其所有后代。

思路分析

此题可以采用递归的方法来解决。

定义一个返回值类型Result:

class Result:
    def __init__(self, is_bst, min_val, max_val, cnt):
        self.is_bst = is_bst           # 子树是否为BST
        self.min_val = min_val         # 子树中最小值
        self.max_val = max_val         # 子树中最大值
        self.cnt = cnt                 # 子树节点数目

对于一个节点node,可以分以下四种情况:

  1. node 为空,返回 Result(True, inf, -inf, 0)
  2. node 只有左子树,递归遍历其左子树,返回值为 Result(is_bst, min_val, max_val, cnt)
  3. node 只有右子树,递归遍历其右子树,返回值为 Result(is_bst, min_val, max_val, cnt)
  4. node 左右子树均有,分别递归遍历左右子树,得到两个 Result,此时需要合并两个 Result,在此不做讨论,具体请看代码实现。
代码实现
class Solution:
    def largestBSTSubtree(self, root: TreeNode) -> int:
        self.res = 0
        
        def dfs(node):
            if not node:
                return Result(True, float('inf'), float('-inf'), 0)
            
            left_res = dfs(node.left)
            right_res = dfs(node.right)
            
            is_bst = left_res.is_bst and right_res.is_bst and (left_res.max_val < node.val < right_res.min_val)
            
            if is_bst:
                cnt = left_res.cnt + right_res.cnt + 1
                self.res = max(self.res, cnt)
            else:
                cnt = 0
            
            return Result(is_bst, min(left_res.min_val, right_res.min_val, node.val), max(left_res.max_val, right_res.max_val, node.val), cnt)
        
        dfs(root)
        return self.res
复杂度分析

时间复杂度:$O(n)$

空间复杂度:$O(h)$,其中 $h$ 是二叉树的高度。在递归过程中,栈空间的最大使用次数等于树高。