简体   繁体   English

2个叶子节点之间的最大路径和(GeeksForGeeks)

[英]Maximum Path Sum between 2 Leaf Nodes(GeeksForGeeks)

Given a binary tree in which each node element contains a number.给定一个二叉树,其中每个节点元素都包含一个数字。 Find the maximum possible sum from one leaf node to another.找到从一个叶节点到另一个叶节点的最大可能总和。

Example 1:示例 1:

Input :      
           3                               
         /    \                          
       4       5                     
      /  \      
    -10   4                          

Output: 16

Explanation : Maximum Sum lies between leaf node 4 and 5. 4 + 4 + 3 + 5 = 16.说明:最大和位于叶节点 4 和 5 之间。4 + 4 + 3 + 5 = 16。

Example 2:示例 2:

Input :    
            -15                               
         /      \                          
        5         6                      
      /  \       / \
    -8    1     3   9
   /  \              \
  2   -3              0
                     / \
                    4  -1
                       /
                     10  

Output :  27

Explanation: The maximum possible sum from one leaf node to another is (3 + 6 + 9 + 0 + -1 + 10 = 27)说明:从一个叶节点到另一个叶节点的最大可能总和为 (3 + 6 + 9 + 0 + -1 + 10 = 27)

This is the solution:这是解决方案:

'''
# Node Class:
class Node:
    def _init_(self,val):
        self.data = val
        self.left = None
        self.right = None
        '''
res = -999999999
def maxPathSumUtil(root):
    global res
    if root is None:
        return 0
    
    if root.left is None and root.right is None:
        return root.data

    ls=maxPathSumUtil(root.left)
    rs=maxPathSumUtil(root.right)
    
    if root.left and root.right:
        res=max(res,ls+rs+root.data)
        return max(ls+root.data,rs+root.data) #Line: Problem
    if root.left is None:
        return rs+root.data
    else:
        return ls+root.data


def maxPathSum(root):
    global res
    res = -999999999
    maxPathSumUtil(root)
    return res

Can anyone tell me why do we use return max(ls+root.data,rs+root.data) .谁能告诉我为什么我们使用return max(ls+root.data,rs+root.data) And if we do use return max(ls+root.data,rs+root.data) for checking the maximum value then why do we use res=max(res,ls+rs+root.data) and not just res = max(ls+root.data,rs+root.data) .如果我们确实使用return max(ls+root.data,rs+root.data)来检查最大值,那么为什么我们使用res=max(res,ls+rs+root.data)而不仅仅是res = max(ls+root.data,rs+root.data)

EDIT:编辑:

For example:例如:

Let's take this tree for example:

             10
           /   \
         8      2
       /  \
     3     5

In this, after recursive calls, ls becomes 3 and rs becomes 5. res becomes ls+rs+root.data which is 3+5+8 = 16. Then return max(ls+root.data,rs+root.data) which is max(11,13) = 13. Now after this according to me the function should just return 13 but that does not happen.在这里,递归调用后, ls变为3, rs变为5。 res变为ls+rs+root.data ,即3+5+8=16。然后return max(ls+root.data,rs+root.data)这是 max(11,13) = 13。现在根据我的说法,在此之后,该函数应该只返回 13,但这不会发生。 Even though return is not a recursive statement.即使return不是递归语句。 How is the control flow of the code happening?代码的控制流是如何发生的?

There are two things that are measured in parallel during execution:在执行期间并行测量两件事:

  • ls+rs+root.data is the max path in the tree rooted by root , between two of the leaves below it. ls+rs+root.data是以root的树中的最大路径,位于其下方的两个叶子之间。 So it is (the value) of a leaf -to-leaf path所以它是到叶路径的(值)
  • The function return value is the maximum path from root to any of the leaves below it.函数返回值是从root到它下面的任何叶子的最大路径。 So it is (the value) of a root -to-leaf path所以它是到叶路径的(值)

These are two different concepts and should not be mixed up.这是两个不同的概念,不应混为一谈。

Both ls and rs are function return values: ls represents the maximum path from root.left to a leaf. lsrs都是函数返回值: ls表示从root.left到叶子的最大路径。 And in the same way rs represents the maximum path from root.right to a leaf.以同样的方式rs表示从root.right到叶子的最大路径。

ls+rs+root.data on the other hand, represents a path from leaf to leaf passing through root .另一方面, ls+rs+root.data表示从叶子到叶子通过root的路径。

res should be updated if that latter expression is greater than res , hence the max() . res应如果后者表达大于被更新res ,因此max()

But the function's return value should not represent a leaf-to-leaf path, but a root-to-leaf path.但是函数的返回值不应该代表叶到叶的路径,而是根到叶的路径。 So that is why we have:这就是为什么我们有:

return max(ls+root.data,rs+root.data)

This tells the caller what the maximum root-to-leaf path is, not what the maximum leaf-to-leaf path is.这告诉调用者最大根到叶路径是什么,而不是最大叶到叶路径是什么。 The latter is used for determining res , not the function's return value.后者用于确定res ,而不是函数的返回值。

I hope this clarifies the distinction between these two concepts and the roles they play in the algorithm.我希望这可以澄清这两个概念之间的区别以及它们在算法中的作用。

The example这个例子

You presented this tree as example:您以这棵树为例:

         10
       /   \
     8      2
   /  \
 3     5

Indeed, when the function is called for the node 8, it:实际上,当为节点 8 调用该函数时,它:

  • sets res to 16 (the max path between two leaves below the node)res设置为 16(节点下方两个叶子之间的最大路径)
  • returns 13 (the max path from the node to one of its leaves)返回 13(从节点到其叶子之一的最大路径)

You then ask:然后你问:

Now after this according to me the function should just return 13 but that does not happen.现在根据我的说法,这个函数应该只返回 13 但这不会发生。

But it does happen like that.但它确实是这样发生的。 You should however not forget that this is the return value of maxPathSumUtil , not of maxPathSum .但是,您不应忘记这是maxPathSumUtil的返回值,而不是maxPathSum的返回值。 Also, this is not the top-level call of maxPathSumUtil .此外,这不是maxPathSumUtil的顶级调用。 The value 13 is returned to another execution context of maxPathSumUtil , where root is the node 10. Then -- after another recursive call is made (with root equal to node 2), this top-level execution of the function maxPathSumUtil will:值 13 返回到maxPathSumUtil另一个执行上下文,其中root是节点 10。然后——在进行另一个递归调用后( root等于节点 2),函数maxPathSumUtil这个顶级执行将:

  • set res to 25 (the max path between two leaves below the node 10)res设置为 25(节点 10 下方两个叶子之间的最大路径)
  • return 23 (the max path from the node 10 to one of its leaves)返回 23(从节点 10 到其叶子之一的最大路径)

This toplevel call was made from within maxPathSum , which ignores the value returned by maxPathSumUntil .这个顶级调用是从maxPathSum内部maxPathSum ,它忽略maxPathSumUntil返回的值。 It only takes the value of res (25), and returns that :只需要值res (25),并返回如下

maxPathSumUtil(root)  # notice that return value is ignored.
return res

At each node, we have to check whether that node's left and right child resulted in max path.在每个节点,我们必须检查该节点的左右子节点是否导致最大路径。 But when we return, we need to return either the left or right path depending upon whichever is max.但是当我们返回时,我们需要根据最大值返回左路径或右路径。 Let's take this tree for example:我们以这棵树为例:

         10
       /   \
     8      2
   /  \
 3     5

In this, after recursive calls, ls becomes 3 and rs becomes 5. res becomes ls+rs+root.data which is 3+5+8 = 16. So res(result) will be updated to 16, and return will be max(11,13) which is 13. Now this 13 value will be used by node 10 as ls(left value).在这里,递归调用后,ls变为3,rs变为5.res变为ls+rs+root.data,即3+5+8=16。所以res(result)将更新为16,return将是max (11,13) 即 13。现在这个 13 值将被节点 10 用作 ls(left value)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM