Given a binary tree, find the maximum path sum.
For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root.
For example:
Given the below binary tree,
1 / \ 2 3
Return 6
.
对于这个题,貌似网上并没有太详细的解释,所以我决定写一篇比较详细的。主要参考博友喜刷刷的思路。
举个例子说明吧:
1. 假设我们现在站在根节点-2的位置上。此时有两种最大路径和的可能:
a:左子树 + -2 + 右子树
b:max(左子树, 右子树) + -2;
2. 然后我们移动到左子树-7的位置上。同样的有两种可能:
a:左子树 + -7 + 右子树 = 4 + -7 + 10 = 7
b:max(左子树, 右子树) + -7 = max(4, 10) + -7 = 3
由于1中的两种情况都需要知道左子树和右子树的值,到底要把2中的哪个数字返回给步骤1呢?答案是:3
因为如果我们返回7给步骤1,那意味着我们在-2的左子树中选择了一条“左-根-右”格式的子树,也就是这条路径变成了:(-2) - (4) - (-7) - (10),然而-2是无法直接到达4 或者10的,就是中间出现了回路。换言之要返回给-2的,一定是“左-根”或者“根-右”的形式,这样才保证不会出现回路。
返回了(-7) - (10) 的和给-2后,还要考虑一个问题:可能刚才那个不能返回的“左-跟-右”的路径就是最大的值,因为节点可能是负数,所以用一个变量来保存对于每一个节点的“左-根-右”形式的路径和。
3. 当我们返回到根节点-2的位置的时候,左边的最大路径为(-7) - (10)= 3,右边最大路径为(3),我们开始讨论那两种情况:
a:左子树 + -2 + 右子树 = 3 + -2 + 3 = 4 即:10 - (-7) - (-2) - 3
b:max(左子树, 右子树) + -2 = max(3, 3) + -2 = 1 即:10 - (-7)-(-2) 或者 (-2)- 3
然而实际上的最大值应该是我们已经保存的4 -(-7)- 10 = 7这条路径。
注意:然而事实上答案是错的,因为节点10自己比所有路径的和都大,所以根据这个图,答案应该是10,举这个例子就是为了帮助理解,如果有小伙伴可以帮我举一个更合适的例子,感激不尽,也希望不会对大家造成误导。
到这里基本思路说完了,可能还是让大家觉得很晕,看看代码也许就明白了。请相信,我尽力了。。。
class Solution {
public:
int maxPathSum(TreeNode* root) {
int maxSum = INT_MIN;
int whatever = findMax(root, maxSum);
return maxSum;
}
int findMax(TreeNode* root, int& maxSum) {
if (root == NULL) return 0;
int left = 0, right = 0;
if (root->left != NULL) {
left = findMax(root->left, maxSum);
}
if (root->right != NULL) {
right = findMax(root->right, maxSum);
}
int left_or_right_root = max(left, right) + root->val;
int left_root_right = left + root->val + right;
maxSum = max(maxSum, max(left_or_right_root, left_root_right));
return max(0, left_or_right_root);
}
};