题目来源:🔒 LeetCode 333:最大二叉搜索子树
问题抽象: 给定一个二叉树的根节点 root,要求找出该树中节点数量最多的子树,且该子树必须是二叉搜索树(BST),满足以下核心需求:
-
子树定义与性质:
- 子树包含当前节点、所有后代节点及其连接关系;
- 目标子树需严格满足 BST 规则:
- 左子树所有节点值 < 根节点值;
- 右子树所有节点值 > 根节点值;
- 左、右子树自身也必须是 BST。
-
优化目标:
- 在所有满足 BST 性质的子树中,选择包含节点数最多的子树;
- 若存在多个相同大小的最大 BST 子树,返回任意一个均可。
-
边界处理:
- 空树(
root = null)视为节点数为0的 BST; - 单节点树(无子树)视为有效 BST(节点数=1);
- 子树必须完全独立于原树结构(即子树不能包含非后代节点)。
- 空树(
输入:二叉树根节点 root(节点值范围整型,树节点数 ≥ 0)
输出:最大 BST 子树的节点数量(整数)。
解题思路
题目要求找出二叉树中最大的二叉搜索子树(BST),并返回其节点数。子树必须包含所有后代节点。我们采用后序遍历(DFS)自底向上处理每个节点,在递归过程中收集子树的关键信息,并判断当前子树是否为BST。
关键步骤
-
递归设计:每个递归返回一个包含4个属性的结果对象:
min:当前子树的最小值max:当前子树的最大值size:当前子树的节点总数isBST:当前子树是否为BST
-
空节点处理:空节点返回特殊结果(
min=MAX_VALUE,max=MIN_VALUE,size=0,isBST=true),避免影响父节点判断。 -
BST判断条件:
- 左右子树均为BST
- 当前节点值 > 左子树的最大值(左子树非空时)
- 当前节点值 < 右子树的最小值(右子树非空时)
-
更新最大BST:若当前子树是BST,则用其节点数更新全局最大值。
-
非BST处理:仍需计算当前子树的
min/max/size(用于父节点判断),但不更新全局最大值。
代码实现(Java版)
class Solution {
private int maxSize = 0; // 全局变量记录最大BST节点数
public int largestBSTSubtree(TreeNode root) {
dfs(root);
return maxSize;
}
private Result dfs(TreeNode node) {
if (node == null) {
return new Result(Integer.MAX_VALUE, Integer.MIN_VALUE, 0, true);
}
Result left = dfs(node.left);
Result right = dfs(node.right);
// 计算当前子树的最小值、最大值和节点总数
int curMin = Math.min(node.val, Math.min(left.min, right.min));
int curMax = Math.max(node.val, Math.max(left.max, right.max));
int curSize = left.size + right.size + 1;
boolean isBST = false;
// 判断当前子树是否为BST
if (left.isBST && right.isBST) {
boolean leftValid = (left.size == 0) || (node.val > left.max);
boolean rightValid = (right.size == 0) || (node.val < right.min);
if (leftValid && rightValid) {
isBST = true;
maxSize = Math.max(maxSize, curSize); // 更新全局最大值
}
}
return new Result(curMin, curMax, curSize, isBST);
}
// 内部类封装子树信息
static class Result {
int min; // 子树最小值
int max; // 子树最大值
int size; // 子树节点总数
boolean isBST; // 是否为BST
Result(int min, int max, int size, boolean isBST) {
this.min = min;
this.max = max;
this.size = size;
this.isBST = isBST;
}
}
}
代码说明
- 全局变量:
maxSize动态记录遍历过程中发现的最大BST节点数。 - 递归函数
dfs:- 终止条件:节点为空时返回特殊Result对象。
- 递归过程:先处理左右子树,再计算当前子树信息。
- BST判断:通过检查左右子树状态及节点值关系确定当前子树是否为BST。
- 更新逻辑:当前子树是BST时更新
maxSize。
- Result类:封装子树的关键信息,便于递归传递。
- 边界处理:
- 空节点:
min=MAX_VALUE,max=MIN_VALUE确保不影响父节点比较。 - 叶子节点:自动满足BST条件(节点数=1)。
- 空节点:

598

被折叠的 条评论
为什么被折叠?



