124. Binary Tree Maximum Path Sum

来源:互联网 发布:特效软件手机版 编辑:程序博客网 时间:2024/04/29 18:50

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);    }};


0 0