Leetcode #124 Binary Tree Maximum Path Sum

Binary Tree Maximum Path Sum

题目描述
给出一颗二叉树,每个树节点有一个整数权值。
现在要求从树上找出一条路径,使得权值之和最大,问这个最大权值之和是多少。

算法分析
一开始我的想法是用树路径的倍增算法,然后找LCA什么之类的,结果发现都想歪了。
首先这里声明为每个树节点声明两个值:

  • ans:以当前节点为根节点,且经过当前节点的路径的权值之和的最大值
  • maxPath:以当前节点为根节点,同时以当前节点为路径端节点,所能求得的路径权值之和的最大值

那么我们有以下两个式子可以求得上述两个值:

  • now.ans=left.maxPath+right.maxPath+now.val
  • now.maxPath=max(left.maxPath,right.maxPath)+now.val
  • left 为左儿子节点, right 为右儿子节点, val 表示节点权值。

显然,我们从所有节点的ans中选出最大的,就是题目要的结果。
因此我们只需要从根节点开始做一次DFS就得出结果。
注意:有一堆的细节问题。由于题目说的节点权值是可以为负数的,所以要特别处理负数(这会使得实际代码中的运算跟上述两个式子不同,但思想是一致的)。还有就是一些空节点之类的问题。
时间复杂度:O(n)

代码

/**
 * 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 maxPathSum(TreeNode* root) {
        if (root == NULL) return 0;
        tree now= tree(root);
        finalAns= now.ans;
        dfs(now);
        return finalAns;
    }
private:
    struct tree
    {
        TreeNode* node;
        int ans;
        int maxPath;
        tree(TreeNode* t):node(t) 
        {
            if (t==NULL)
            {
                ans=0;
                maxPath=0;
            }
            else
            {
                ans=node->val;
                maxPath=ans;
            }
        }
    };
    int finalAns;
    void dfs(tree &now)
    {
        tree left = tree(now.node->left);
        tree right = tree(now.node->right);
        if (left.node == NULL && right.node == NULL)
        {
            if (now.ans>finalAns) finalAns=now.ans;
            return;
        }
        if (left.node!=NULL) dfs(left);
        if (right.node!=NULL) dfs(right);
        if (left.maxPath > 0) now.ans+=left.maxPath;
        if (right.maxPath > 0) now.ans+=right.maxPath;
        now.maxPath+=max(max(left.maxPath,right.maxPath),0);
        if (now.ans>finalAns) finalAns=now.ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值