最大二叉搜索子树
难度:
标签:
题目描述
代码结果
运行时间: 26 ms, 内存: 18.1 MB
/*
* 思路:
* 1. 使用递归方法,通过流的方式计算每个节点为根的子树的大小。
* 2. 对于每个节点,判断其左子树和右子树是否为二叉搜索树(BST)。
* 3. 记录最大BST的大小。
*/
import java.util.stream.Stream;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public class Solution {
class ResultType {
boolean isBST;
int size;
int minVal, maxVal;
ResultType(boolean isBST, int size, int minVal, int maxVal) {
this.isBST = isBST;
this.size = size;
this.minVal = minVal;
this.maxVal = maxVal;
}
}
private int maxBSTSize = 0;
public int largestBSTSubtree(TreeNode root) {
helper(root);
return maxBSTSize;
}
private ResultType helper(TreeNode node) {
if (node == null) {
return new ResultType(true, 0, Integer.MAX_VALUE, Integer.MIN_VALUE);
}
ResultType left = helper(node.left);
ResultType right = helper(node.right);
if (Stream.of(left.isBST, right.isBST).allMatch(b -> b) && node.val > left.maxVal && node.val < right.minVal) {
int size = left.size + right.size + 1;
maxBSTSize = Math.max(maxBSTSize, size);
return new ResultType(true, size, Math.min(left.minVal, node.val), Math.max(right.maxVal, node.val));
} else {
return new ResultType(false, 0, 0, 0);
}
}
}
解释
方法:
该题解使用深度优先遍历(DFS)的方法来遍历二叉树的每个节点。对于每个节点,判断其是否能成为一个二叉搜索树(BST)的根节点。如果当前节点能成为BST的根,那么以该节点为根的子树就是一个BST,记录其节点数,并与当前最大BST节点数比较,更新最大值。DFS函数返回一个元组,包含当前子树是否为BST、子树的最小值、最大值和节点数。通过比较当前节点与其左右子树的最大最小值,可以判断当前节点是否能成为BST的根。
时间复杂度:
O(n)
空间复杂度:
O(h),最坏情况下O(n),平均情况下O(logn)
代码细节讲解
🦆
在DFS的返回值中,元组的各个部分分别代表什么?具体如何使用这些信息来判断一个节点是否能成为BST的根节点?
▷🦆
题解中提到,如果左右子树都是BST且满足一定条件,当前节点也可以是BST的根。这里的条件是什么?为什么需要这些条件?
▷🦆
在处理只有左子树或只有右子树的情况时,题解如何确保当前节点的值与其子树的值满足BST的性质?
▷🦆
题解中没有明确提到如何处理当前节点的左子树或右子树不是BST的情况。这种情况应该如何处理?
▷