1.题目简述
给你一棵以 root 为根的 二叉树 ,请你返回 任意 二叉搜索子树的最大键值和。
示例
输入:root = [1,2,3,1,5,2,5,null,null,null,null,null,null,4,6]
输出:20
解释:键值为 3 的子树是和最大的二叉搜索树
详情请查看 LeetCode 官网:1373. 二叉搜索子树的最大键值和 - 力扣(LeetCode)
2.方法
通过 后序遍历遍历二叉树。遍历到某一节点时,进行如下的判断:
- 判断其左子树和右子树是否为二叉搜索树
- 判断节点值是否大于左子树最大值
- 判断节点值是否小于右子树的最小值
当都符合条件时,则说明以该节点为根的树是二叉搜索树。
为了实现以上的目标,可以定义一个子树结构(SubTree):
- boolean isBST:是否为二叉搜索树
- int maxValue:当前子树的最大节点值
- int minValue:当前子树的最小节点值
- int sumValue:当前子树的节点值和
class Solution {
final int INF = 40002;
int ans;
public int maxSumBST(TreeNode root) {
if(root == null) return 0;
ans = 0;
dfs(root);
return ans;
}
SubTree dfs(TreeNode root){
if(root == null){
// 节点为空时,返回一个二叉搜索树的子树
return new SubTree(true,-INF,INF,0);
}
SubTree left = dfs(root.left);
SubTree right = dfs(root.right);
// 进行文中所说的判断
if(left.isBST && right.isBST && root.val>left.maxValue && root.val<right.minValue){
int sum = left.sumValue + right.sumValue + root.val;
ans = Math.max(ans,sum);
return new SubTree(true,Math.max(root.val,right.maxValue),Math.min(root.val,left.minValue),sum);
}else{
return new SubTree(false,0,0,0);
}
}
class SubTree{
boolean isBST;
int maxValue;
int minValue;
int sumValue;
public SubTree(boolean isBST,int maxValue,int minValue,int sumValue){
this.isBST = isBST;
this.maxValue = maxValue;
this.minValue = minValue;
this.sumValue = sumValue;
}
}
}