给定一个二叉树,找到其中最大的二叉搜索树(BST)子树,并返回该子树的大小。其中,最大指的是子树节点数最多的。
**二叉搜索树(BST)**中的所有节点都具备以下属性:
-
左子树的值小于其父(根)节点的值。
-
右子树的值大于其父(根)节点的值。
**注意:**子树必须包含其所有后代。
示例 1:

输入:root = [10,5,15,1,8,null,7]
输出:3
解释:本例中最大的 BST 子树是高亮显示的子树。返回值是子树的大小,即 3 。
示例 2:
输入:root = [4,2,7,2,3,5,null,2,null,null,null,null,null,1]
输出:2
提示:
- 树上节点数目的范围是
[0, 104] -104 <= Node.val <= 104
进阶: 你能想出 O(n) 时间复杂度的解法吗?
直接上代码:
java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int largestBSTSubtree(TreeNode root) {
/**空树判断 */
if(root == null) {
return 0;
}
/**获取root的info信息 */
Info info = getInfo(root);
return info.numOfNodes;
}
public Info getInfo(TreeNode root) {
/**叶子节点的判断,叶子节点是BST,节点数是1,最大值和最小值都是自己的值 */
if(root.left == null && root.right == null) {
return new Info(true, 1, root.val, root.val);
}
/**目前只有自己的信息,那就是先按叶子节点的信息设置,后面根据左右子树的信息再修改 */
boolean isBST = true;
int numOfNodes = 1;
int minValue = root.val;
int maxValue = root.val;
/**定义在外面是因为外面要用 */
Info leftInfo = null;
Info rightInfo = null;
/**如果有左子树,再获取左子树的信息,左右子树的信息都不设置节点的数量 */
if(root.left != null) {
leftInfo = getInfo(root.left);
isBST = isBST && leftInfo.isBST && root.val > leftInfo.maxValue;
minValue = Math.min(minValue, leftInfo.minValue);
maxValue = Math.max(maxValue, leftInfo.maxValue);
}
if(root.right != null) {
rightInfo = getInfo(root.right);
isBST = isBST && rightInfo.isBST && root.val < rightInfo.minValue;
minValue = Math.min(minValue, rightInfo.minValue);
maxValue = Math.max(maxValue, rightInfo.maxValue);
}
/**整棵树是BST,就根据左右子树的信息设置,同时加上所有的节点数 */
if(isBST) {
numOfNodes += root.left != null? leftInfo.numOfNodes : 0;
numOfNodes += root.right != null? rightInfo.numOfNodes : 0;
minValue = root.left != null? leftInfo.minValue : root.val;
maxValue = root.right != null? rightInfo.maxValue : root.val;
} else {
/**如果不是的话,谁的numOfNodes(以当前节点为根的树上所有的BST里的最大节点树)大取谁的,
这样即使自己不是也可以把信息带到树的根节点 */
numOfNodes = Math.max(leftInfo != null? leftInfo.numOfNodes : 0 , rightInfo != null? rightInfo.numOfNodes : 0);
}
return new Info(isBST, numOfNodes, minValue, maxValue);
}
}
/**根据题目意思,这个树本身可能不是二叉搜索树,我们需要在它身上找到是二叉搜索树并且节点最多的
所以我们需要以下几个信息:1.是否是二叉搜索树 2.节点数量 3.最大值 4.最小值
其中3和4是用来判断是在知道当前树的左右子树的信息时候判断当前树是否是二叉搜索树用的*/
class Info {
/**当前树是不是搜索二叉树 */
boolean isBST;
/**当前树上最大的搜索二叉树的节点数量 */
int numOfNodes;
/**当前树的最大值 */
int maxValue;
/**当前树的最小值 */
int minValue;
public Info(boolean isBST, int numOfNodes, int minValue, int maxValue) {
this.isBST = isBST;
this.numOfNodes = numOfNodes;
this.minValue = minValue;
this.maxValue = maxValue;
}
}
运行结果

