124. 二叉树中的最大路径和

124 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

124. 二叉树中的最大路径和

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

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

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

示例 1:

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

image.png

示例 2:

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

 

image.png

数据范围:

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

思路

树形dp 基础题
我们可以先求出所有点到根节点的路径上的最大值
然后在去dfs一次,求出对于每一个点对与上面和下面所形成的最大值

image.png

比如这样一个图,我们对每一个点的上面节点的最大值和当前节点的左右儿子的最大值计算一下
就可以求出全局最大值了
比如2这个点, 可以来自 3 和 5的值或者 父亲节点的值,也就是 1点来的值

代码

class Solution {
public:
    int maxPathSum(TreeNode* root) {
        unordered_map<TreeNode*, pair<int, int>> mp;
        #define x first
        #define y second
        auto dfs = [&](auto&& self, TreeNode* root) -> void{
            if (root->left) {
                self(self, root->left);
                mp[root].x = 
                    max(mp[root->left].x, mp[root->left].y) + root->left->val;
            }
            if (root->right) {
                self(self, root->right);
                mp[root].y = 
                    max(mp[root->right].x, mp[root->right].y) + root->right->val;
            }
        };
        int ans = INT_MIN;
        auto tfs = [&](auto&& self, TreeNode* root, int top) -> void {
            top = max(0, top);
            int ma = max(max(mp[root].x, mp[root].y), 0);
            ans = max(ans, ma + top + root->val);
            if (root->left) 
                self(self, root->left, max(top, mp[root].y) + root->val);
            if (root->right)
                self(self, root->right, max(top, mp[root].x) + root->val);
        };
        dfs(dfs, root);
        tfs(tfs, root, 0);
        #undef x
        #undef y
        return ans;
    }
};