zoukankan      html  css  js  c++  java
  • Binary Tree Maximum Path Sum

    Given a binary tree, find the maximum path sum.

    The path may start and end at any node in the tree.

    For example:
    Given the below binary tree,

           1
          / 
         2   3
    

    Return 6.

    关键点1:

    分析:http://fisherlei.blogspot.com/2013/01/leetcode-binary-tree-maximum-path-sum.html

    For each node like following, there should be four ways existing for max path:


    1. Node only (因为本题中的节点可能是负值!)
    2. L-sub + Node
    3. R-sub + Node
    4. L-sub + Node + R-sub

    Keep trace the four path and pick up the max one in the end.  

    关键点2:明确递归函数的返回值是什么:这本题中返回值表示通过root节点能走到root的parent的最大和,这个值作为返回对象返给调用父函数。

    树结构显然用递归来解,解题关键:

    1、对于每一层递归,只有包含此层树根节点的值才可以返回到上层。否则路径将不连续。

    2、返回的值最多为根节点加上左右子树中的一个返回值,而不能加上两个返回值。否则路径将分叉。

    在这两个前提下有个需要注意的问题,最上层返回的值并不一定是满足要求的最大值,

    因为最大值对应的路径不一定包含root的值,可能存在于某个子树上。

    因此解决方案为设置全局变量maxSum,在递归过程中不断更新最大值。

    参考:http://www.xuebuyuan.com/2102572.html (了解返回值与求得的最大值不是一样的)

    因为要计算任意path的最大值, 根据题意要求,可以理解为可以用一笔画完(不重复,不走回头路)的曲线覆盖的节点就算是一条合法的path。

    用一个helper函数getSum(TreeNode* root, int &ret)来中序遍历整个tree,这个函数返回值是以root为根的子树的包含root节点本身的一个序列的最大值,ret的值是到遍历完当前root指定的子树后,已经出现过的所有子序列中的最大值; 这样一来,返回至可以被用来继续计算当前root的父亲节点所在的子树的最大值;

    这样一来,每处理一个节点的时候可以得到包含其左孩子的一个最大合l,一个包含其右孩子的最大和r, 在考虑节点本身的值val, 我们可以得到4种不同的组合
     (l + val), (r + val), val, (l + val + r),  这四个值取最大的一个来和传入的此前最大的值ret比较并赋值(如果ret小于当前算出的最大值); 返回值则是max(l, r,0) + val (必须包含当前节点值的一个最大和值)。

    C++实现代码:

    #include<iostream>
    #include<new>
    #include<climits>
    using namespace std;
    
    //Definition for binary tree
    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;
            int res=INT_MIN;
            helper(root,res);
            return res;
        }
        int helper(TreeNode *root,int &res)
        {
            if(root==NULL)
                return 0;
            int left=helper(root->left,res);
            int right=helper(root->right,res);
            int val=root->val;
            if(left>0)
                val+=left;
            if(right>0)
                val+=right;
            int ret=max(root->val,root->val+max(left,right));
            //res指的是所有root中的所有路径的最大值,不一定以root为根,因此不能返回给上层
            res=max(res,max(val,ret));
            //返回值表示的是以root为根的最大值
            return ret;
        }
        void createTree(TreeNode *&root)
        {
            int i;
            cin>>i;
            if(i!=0)
            {
                root=new TreeNode(i);
                if(root==NULL)
                    return;
                createTree(root->left);
                createTree(root->right);
            }
        }
    };
    
    int main()
    {
        Solution s;
        TreeNode *root;
        s.createTree(root);
        cout<<s.maxPathSum(root)<<endl;
    }

    注意其中ret和res的区别,其实res是包含ret的最大值的,但是res不能用了返回给上层,如果即选择了root的左子树又选择了右子树,则如果返回上层,会出现分支的情况。

    简单一点的写法:

    class Solution {
    public:
        int maxPathSum(TreeNode *root) {
            int ret = INT_MIN;
            getSum(root, ret);
            return ret;
        }
        
    private:
        int getSum(TreeNode *node, int &ret) {
            if (node == NULL) return 0;
            int l = getSum(node->left, ret);
            int r = getSum(node->right, ret);
         //cret是返回值,如果要返回到上层节点root,cret要么是root的左子树与root的和或者是右子树与root的和或者直接就是root的值,取三者中较大的
    int cret = max(node->val, max(l, r) + node->val);
         //ret维持一个局部的最大值   ret
    = max(ret, max(cret, l + r + node->val)); return cret; } };
  • 相关阅读:
    APP开发收藏的几个网址,APP性能监测
    MAC 安装STF
    更新react 之后 出现 can not find ‘@babel/runtime/helpers/esm/createSuper’ 提示
    react 相关笔记
    jenkins 配置子节点 关键在端口号和下方代理配置
    移动APP测试8点注意事项
    自动部署java项目,热部署方式
    ubuntu搭建elk服务器
    数据库常用操作,sql server; mysql
    windows 关闭端口占用及其他常见操作
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4131850.html
Copyright © 2011-2022 走看看