题目 二叉树中的最大路径和
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
示例 1:
输入: [1,2,3]
1
/ \
2 3
输出: 6
示例 2:
输入: [-10,9,20,null,null,15,7]
-10
/ \
9 20
/ \
15 7
输出: 42
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-maximum-path-sum
思路
这个题目没有做过的话确实很容易陷入误区。比如我刚看到题目的时候就觉得大概是将二叉树的通路转化为图,然后DFS或者BFS遍历一下,再利用动态规划得到最终的答案。结果看了眼官解,发现自己的思路确实是非常错误。其实只要遍历一下二叉树,记录每个节点可以得到的最大值即可,这个思路如下所示:
我们用这个示例输入做例子:
-10
/ \
9 20
/ \
15 7
我们可以将它更新为如下的二叉树,从叶子结点开始,更新的值为左右节点的最大值加上本节点的值。例如20节点就更新为35,-10则更新为25:
25
/ \
9 35
/ \
15 7
其实代码量不大,如下所示:
class Solution {
public:
int maxPathSum(TreeNode* root) {
int answer = 0;
return transverse(root, answer);
}
int transverse(TreeNode *root, int maximum) {
if (root == NULL) {
return maximum;
}
if (root->left == NULL && root->right == NULL) {
maximum = max(root->val, maximum);
return maximum;
}
maximum = transverse(root->left, maximum);
maximum = transverse(root->right, maximum);
if (root->left == NULL) {
root->val = root->right->val + root->val;
return max(maximum, root->val);
}
if (root->right == NULL) {
root->val = root->left->val + root->val;
return max(maximum, root->val);
}
root->val = max(root->left->val, root->right->val) + root->val;
return max(maximum, root->val);
}
};
然后我神奇的发现,我理解错意思了……因为这个各子节点的最大值是从上往下走的时候,连一条线得到的最大值。如果以本节点为根结点,那么实际可以连接到的最大值是左右节点之和加上本节点的值。赶紧更改一下代码,以及修掉了几个边缘条件没考虑到的bug:
class Solution {
public:
int maxPathSum(TreeNode* root) {
if (root == NULL) {
return 0;
}
int answer = root->val;
return transverse(root, answer);
}
int transverse(TreeNode *root, int maximum) {
if (root == NULL) {
return maximum;
}
if (root->left == NULL && root->right == NULL) {
return max(root->val, maximum);
}
int value = root->val;
maximum = transverse(root->left, maximum);
maximum = transverse(root->right, maximum);
if (root->left == NULL) {
root->val = max(root->right->val + root->val, value);
return max(maximum, root->val);
}
if (root->right == NULL) {
root->val = max(root->left->val + root->val, value);
return max(maximum, root->val);
}
root->val = max(max(root->left->val, root->right->val) + value, value);
return max(max(root->val, root->left->val + root->right->val + value), maximum);
}
};