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; } };
  • 相关阅读:
    Generate Parentheses
    Length of Last Word
    Maximum Subarray
    Count and Say
    二分搜索算法
    Search Insert Position
    Implement strStr()
    Remove Element
    Remove Duplicates from Sorted Array
    Remove Nth Node From End of List
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4131850.html
Copyright © 2011-2022 走看看