剑指 Offer II 051. 节点之和最大的路径
题目描述
给定一个非空二叉树,找到路径权值和的最大值。
在这道题目中,路径是指从树中某个节点开始,沿着树中的边走,走到某个节点为止,路过的所有节点的集合。
路径的权值和是指路径中所有节点的权值的总和。
样例1
输入:[1,2,3]
1
/ \
2 3
输出:6
样例2
输入:[-10,9,20,null,null,15,7]
-10
/ \
9 20
/ \
15 7
输出:42
算法
(递归,树的遍历) O(n2)
树中每条路径,都存在一个离根节点最近的点,我们把它记为割点,用割点可以将整条路径分为两部分:从该节点向左子树延伸的路径,和从该节点向右子树延伸的部分,而且两部分都是自上而下延伸的。如下图所示,蓝色的节点为割点:
我们可以递归遍历整棵树,递归时维护从每个节点开始往下延伸的最大路径和。
对于每个点,递归计算完左右子树后,我们将左右子树维护的两条最大路径,和该点拼接起来,就可以得到以这个点为割点的最大路径。
然后维护从这个点往下延伸的最大路径:从左右子树的路径中选择权值大的一条延伸即可。
时间复杂度分析:每个节点仅会遍历一次,所以时间复杂度是 O(n)。
class Solution {
public:
int ans ;
int maxPathSum(TreeNode* root) {
ans = INT_MIN ; //记录答案
dfs(root) ;
return ans ;
}
int dfs(TreeNode* root){
if(!root) return 0 ;
int left = max(0,dfs(root -> left)) ; //求左子树的最大路径
int right = max(0,dfs(root -> right)) ; //求右子树的最大路径
ans = max(ans,root -> val + left + right) ; //更新答案
return root -> val + max(left,right) ; //返回当前根节点的最大路径
}
};