题目
给定一个二叉树,返回其包含的最大(节点数量最多)二叉搜索树的大小
输入: root = [10,5,15,1,8,null,7]
输出: 3
解释: 本例中最大的 BST 子树是高亮显示的子树。返回值是子树的大小,即 3 。
解法
- Brute Force 遍历该树,对每个节点判断其树是否是二叉搜索树(以该节点为根节点的树),时间复杂度为O(N2)
- 树的动态规划:使用后序遍历,某节点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);
}
}
}