算法分析与设计,第17周博客
124. Binary Tree Maximum Path Sum
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
.
所给的二叉树的结构如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
可以看到,只有值和左右子节点,并不包含父节点的指针。所以需要从根节点往下搜索。对于二叉树这种递归定义的结构,使用递归的方法来解决是最直接了当的。
题目不要求这条路径一定要包含根节点,所以,这条路径可能存在于某个子树上边,而一条路径一旦将某个子树的左右两部分都包含了,那么这条路径将不能继续往上延伸了。那么,一共有以下几个情况:
- 路径同时包含了某个节点的左右子树,那么这个路径也就会在这个节点里终结。
- 路径至多包含了某个节点的左子树或者右子树,也可能不包含,那么这条路径可以继续往上延伸。
与之对应的,路径所包含的值之和也可能是一下几种情况,用v表示当前节点的值,lv表示其左子树的最大和,rv表示其右子树的最大和:
- sum = v,只包含当前节点,可以往上延伸
- sum = v+lv,包含当前节点和其左子树,可以往上延伸
- sum = v+rv,包含当前节点和其右子树,可以往上延伸
- sum = v+lv+rv,包含当前节点和其左右子树,不可以往上延伸
而其左右子树的最大和则使用相同的方法递归计算出来。那么总体的代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int sum = 0;
int maxPathSum(TreeNode* root) {
if (root == NULL)
return 0;
sum = root->val;
return max(maxSum(root), sum);
}
int maxSum(TreeNode* root) {
if (root == NULL)
return 0;
int v = root->val;
int lv = maxSum(root->left);
int rv = maxSum(root->right);
int mv = v;
if (lv > 0)
mv += lv;
if (rv > 0)
mv += rv;
sum = max(sum, mv);
return max(v, max(lv+v, rv+v));
}
};
最后来看下时间复杂度。对于整棵二叉树而言,其中的每个节点都需要访问一次,而单次访问的时间花销是固定的常量时间,所以时间复杂度是O(n)。