LeetCode 124. Binary Tree Maximum Path Sum

91 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第25天,点击查看活动详情

LeetCode 124. Binary Tree Maximum Path Sum

路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。

路径和 是路径中各节点值的总和。

给你一个二叉树的根节点 root ,返回其 最大路径和 。

 

示例 1:

输入: root = [1,2,3]
输出: 6
解释: 最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6

示例 2:

输入: root = [-10,9,20,null,null,15,7]
输出: 42
解释: 最优路径是 15 -> 20 -> 7 ,路径和为 15 + 20 + 7 = 42

 

提示:

  • 树中节点数目范围是 [1, 3 * 104]
  • -1000 <= Node.val <= 1000

算法

(递归,树的遍历) O(n2) 树中每条路径,都存在一个离根节点最近的点,我们把它记为割点,用割点可以将整条路径分为两部分:从该节点向左子树延伸的路径,和从该节点向右子树延伸的部分,而且两部分都是自上而下延伸的。如下图所示,蓝色的节点为割点:

我们可以递归遍历整棵树,递归时维护从每个节点开始往下延伸的最大路径和。 对于每个点,递归计算完左右子树后,我们将左右子树维护的两条最大路径,和该点拼接起来,就可以得到以这个点为割点的最大路径。 然后维护从这个点往下延伸的最大路径:从左右子树的路径中选择权值大的一条延伸即可。

时间复杂度分析:每个节点仅会遍历一次,所以时间复杂度是 O(n)。

C++ 代码

/**
 * 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 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, left + root->val + right);
        return root->val + max(left, right);
    }
};