[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.
这题基本的做法还是可以分成,最大路径出现在左子树,右子树,以及通过根节点三种情况讨论,复杂度为O(nlogn).复杂度理解参照快排。
代码:
class Solution {
public:
int maxPathSum(TreeNode* root) {
if (root == NULL) return INT_MIN;
if (root->left == NULL && root->right == NULL) return root->val;
int maxleft = maxPathSum(root->left);
int maxright = maxPathSum(root->right);
int maxltor = root->val;
int maxleftconn = maxconn(root->left, 0);
int maxrightconn = maxconn(root->right, 0);
return max(max(maxleft, maxright), maxltor + maxleftconn + maxrightconn);
}
int maxconn(TreeNode* root, int prevSum) {
if (root == NULL) return prevSum;
if (root->left == NULL && root->right == NULL) return max(prevSum, prevSum + root->val);
int maxleftconn = maxconn(root->left, root->val);
int maxrightconn = maxconn(root->right, root->val);
return max(prevSum, prevSum + max(maxleftconn, maxrightconn));
}
};
方法二:
这题其实可以将左右子树中的判断和通过根节点的判断融为一体,减少不必要的递归。
可以记住这种很常用的处理手段。因为实际上所有的判断归根结底都是发生在寻找左边最大路径,右边最大路径,不论是左右相加还是左右取较大,都是基于同样的操作。除了递归,我们可以维持一个maxsum的数来记录所有可能的路径中的最大和。
代码:
class Solution {
public:
int maxPathSum(TreeNode* root) {
int maxsum = INT_MIN;
DFS(root, maxsum);
return maxsum;
}
int DFS(TreeNode* root, int& maxsum) {
if (root == NULL) return 0;
int left = max(0, DFS(root->left, maxsum));
int right = max(0, DFS(root->right, maxsum));
maxsum = max(maxsum, root->val + left + right);
return max(root->val, root->val + max(left, right));
}
};
复杂度为O(n).
同样的操作可以用在另一题上:
543. Diameter of Binary Tree
Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root.
Example:
Given a binary tree
1
/ \
2 3
/ \
4 5
Return 3, which is the length of the path [4,2,1,3] or [5,2,1,3].
Note: The length of path between two nodes is represented by the number of edges between them.
class Solution {
public:
int diameterOfBinaryTree(TreeNode* root) {
int diameter = 0;
DFS(root, diameter);
return diameter;
}
int DFS(TreeNode* root, int& diameter) {
if (root == NULL) return 0;
int left = DFS(root->left, diameter);
int right = DFS(root->right, diameter);
diameter = max(diameter, left + right);
return max(left, right) + 1;
}
};