剑指 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) ;      //返回当前根节点的最大路径
    }
};

Guess you like

Origin blog.csdn.net/m0_46571920/article/details/120953937