题目
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
示例 1:
1
2
3
4
5
6
7
|
输入: [1,2,3]
1
/ \
2 3
输出: 6
|
示例 2:
1
2
3
4
5
6
7
8
9
|
输入: [-10,9,20,null,null,15,7]
-10
/ \
9 20
/ \
15 7
输出: 42
|
题解
这道题倒是简单,很容易就想出来了。对于树的结构来说,无非是左子树、根结点、右子树,那么路径实际上就有下面这几种:
- 根节点
- 左子树+根节点
- 右子树+根节点
- 左子树+根节点+右子树
我们遍历整个树,求上面4种情况的最大值即可。我最开始的实现如下,稍微有点复杂。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
int maxPath(TreeNode* root, int &max_value) {
if (root == nullptr) return INT_MIN;
int left_value = INT_MIN;
int right_value = INT_MIN;
left_value = maxPath(root->left, max_value);
int root_value = root->val;
right_value = maxPath(root->right, max_value);
int left_root_right = root_value;
int right_root = root_value;
int left_root = root_value;
// 为了避免负数相加导致溢出,这里进行判断
if (left_value != INT_MIN && right_value != INT_MIN)
left_root_right += left_value + right_value;
// 同样为了避免溢出,这里进行判断
if (left_value != INT_MIN)
left_root += left_value;
if (right_value != INT_MIN)
right_root += right_value;
// 记录4种情况中的最大值
max_value = max(max_value, root_value);
max_value = max(max_value, left_root);
max_value = max(max_value, right_root);
max_value = max(max_value, left_root_right);
// 返回当前树情况下的最大值
return max(left_root, max(root_value, right_root));
}
int maxPathSum(TreeNode* root) {
int max_value = INT_MIN;
maxPath(root, max_value);
return max_value;
}
|
这里的实现有些蛋疼,因为将初始值设为了INT_MIN
,而当两个INT_MIN
相加时将会导致溢出,导致计算错误,所以这里进行了判断处理。
maxPath
函数的第二个参数用来记录整个遍历过程中的最大值,而maxPath
函数本身会返回当前子树路径的最大值,这个最大值中是一定要包含根结点的,否则将无法形成路径。
在参考了讨论之后,发现我自己的实现比较复杂,主要还是考虑了负数的计算,但实际上负数并不对最大值有效,因此我们可以将它给排除掉。但考虑所有数都为负数的情况,这种情况下某个结点肯定为最大值,因此我们在计算最大值时,是不能将根结点给排除掉的。
参考讨论的实现如下,思路基本相同:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
int maxPath(TreeNode* root, int &max_value){
if (root == nullptr) return 0;
int left = maxPath(root->left, max_value);
int right = maxPath(root->right, max_value);
// 这里使用max排除掉负数
int left_root_right = root->val + max(0, left) + max(0, right);
int ret = root->val + max(0, max(left, right));
max_value = max(max_value, max(left_root_right, ret));
return ret;
}
int maxPathSum(TreeNode* root) {
int max_value = INT_MIN;
maxPath(root, max_value);
return max_value;
}
|