原题目:
Given a binary tree, find the maximum path sum.
The path may start and end at any node in the tree.
For example:
Given the below binary tree,
1 / \ 2 3
Return 6
.
看似简单的一道题目。
首先,要弄清题意,明确题目中的"path"的起点和终点可以是树中的任意节点,这里称之为path1
这与我之前做过的一道题目的path定义不同。我之前做的题目的path定义为:起点是根节点,终点是该跟节点的后辈的path,这里称之为path2
比如拿样例来看,最大的path1是:
2 -- 1 -- 3
而最大的path2 只能是:
1 -- 3
因为 2 和 3 并不是祖先和后辈的关系。
思考算法时,要区分这两种path的区别:
如果要求计算path2,相信大家都会写,一个简单的dfs就可以搞定:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int dfs(TreeNode * root) {
if (root == NULL) return 0;
int left = 0, right = 0;
if (root->left != NULL) left = dfs(root->left);
if (root->right != NULL) right = dfs(root->right);
return max(root->val, max(root->val + left, root->val + right));
}
int maxPathSum(TreeNode *root) {
return dfs(root);
}
};
如果是要求计算path1,则需要再上面的代码基础上,做一点小小的修改。
因为真正合法的路径,是可以由 自身 + 左子节点的path2 + 右子节点的path2 构成。
换句话说,为了使得path1最大,如果左子节点path2大于0,则加入。右子节点path2大于0,也加入。
因此需要设置一个全局变量result,实时更新最大path1值:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
int result = -0x3f3f3f3f;
class Solution {
public:
int dfs(TreeNode * root) {
if (root == NULL) return 0;
int left = 0, right = 0;
if (root->left != NULL) {
left = dfs(root->left);
}
if (root->right != NULL) {
right = dfs(root->right);
}
//注意这一段代码
int cur = root->val;
if (left > 0) cur += left;
if (right > 0) cur += right;
result = max(result, cur);
//注意上面的代码,实时更新result
return max(root->val, max(root->val + left, root->val + right));
}
int maxPathSum(TreeNode *root) {
result = -0x3f3f3f3f;
dfs(root);
return result;//设置一个全局变量
}
};