Day117 | 灵神 | 二叉树 | 二叉搜索树的最大键值和

1373.二叉搜索树的最大键值和

1373. 二叉搜索子树的最大键值和 - 力扣(LeetCode)

关联题目:

98. 验证二叉搜索树 - 力扣(LeetCode),这道题的后序遍历和本题一个思路

思路:

hard题,思路倒也简单,就是后序遍历,判断这棵树是不是二叉树并且自底向上计算这棵子树的和,然后更新最大值

但是虽说思路简单,代码却没有那么好写….

笔者第一次写是用bool返回子树是否是二叉搜索树,只要左右子树是,那就把本节点的值给加上了,所以出错了,因为左右子树都是二叉搜索树不能说算上当前结点也是二叉搜索树

正确的想法应该是自底向上返回左右子树最大值和最小值,从而判断当前结点是不是二叉搜索树

只要不是二叉搜索树,那和就是0,只要是那就是左右子树之和再加本节点的值,再和当前的最大值取一个最大值,就是结果,然后继续向上返回

所以递归函数意义就是向上返回左右边界的当前子树的和,左右边界用来判断是否二叉搜索树,和用来找最大值

完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public:
int ans = 0; // 二叉搜索树可以为空

tuple<int, int, int> dfs(TreeNode *node) {
if (node == nullptr)
return {INT_MAX, INT_MIN, 0};

auto [l_min, l_max, l_sum] = dfs(node->left); // 递归左子树
auto [r_min, r_max, r_sum] = dfs(node->right); // 递归右子树
int x = node->val;
if (x <= l_max || x >= r_min) // 不是二叉搜索树
return {INT_MIN, INT_MAX, 0};

int s = l_sum + r_sum + x; // 这棵子树的所有节点值之和
ans = max(ans, s);

return {min(l_min, x), max(r_max, x), s};
}
int maxSumBST(TreeNode* root) {
dfs(root);
return ans;
}
};