【问题标题】:Maximum Path Sum between 2 Leaf Nodes(GeeksForGeeks)2个叶子节点之间的最大路径和(GeeksForGeeks)
【发布时间】:2020-11-03 16:16:04
【问题描述】:

给定一棵二叉树,其中每个节点元素都包含一个数字。找出从一个叶节点到另一个叶节点的最大可能总和。

示例 1:

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

Output: 16

说明: 最大和位于叶节点 4 和 5 之间。 4 + 4 + 3 + 5 = 16。

示例 2:

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

Output :  27

说明: 一个叶子节点的最大可能和 另一个是 (3 + 6 + 9 + 0 + -1 + 10 = 27)

这是解决方案:

'''
# 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

谁能告诉我为什么我们使用return 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)

编辑:

例如:

Let's take this tree for example:

             10
           /   \
         8      2
       /  \
     3     5

在此,递归调用后,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 但这不会发生。即使return 不是递归语句。代码的控制流程是如何发生的?

【问题讨论】:

  • 2个叶子节点之间的路径也涉及到根节点。请注意,根也可以是子树的子根,不一定要通过树的实际根。

标签: python algorithm data-structures tree


【解决方案1】:

在执行过程中有两件事是并行测量的:

  • ls+rs+root.data 是以root 为根的树中的最大路径,位于其下方的两片叶子之间。所以它是到叶路径
  • 的(值)
  • 函数返回值是从root 到它下面的任何叶子的最大路径。所以它是 root-to-leaf 路径
  • 的(值)

这是两个不同的概念,不应混淆。

lsrs 都是函数返回值:ls 表示从 root.left 到叶子的最大路径。同样rs 表示从root.right 到叶子的最大路径。

另一方面,ls+rs+root.data 表示从叶到叶通过root 的路径。

如果后一个表达式大于res,则应更新res,因此max()

但是函数的返回值不应该代表叶子到叶子的路径,而是根到叶子的路径。这就是为什么我们有:

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

这告诉调用者最大的根到叶路径是什么,而不是最大叶到叶路径是多少。后者用于确定res,而不是函数的返回值。

我希望这能阐明这两个概念之间的区别以及它们在算法中所扮演的角色。

例子

您以这棵树为例:

         10
       /   \
     8      2
   /  \
 3     5

确实,当节点8调用该函数时,它:

  • res 设置为16(节点下方两个叶子之间的最大路径)
  • 返回 13(从节点到其叶子之一的最大路径)

然后你问:

现在根据我的说法,该函数应该只返回 13,但这不会发生。

但它确实就这样发生了。但是你不应该忘记这是maxPathSumUtil 的返回值,而不是maxPathSum 的返回值。此外,这不是maxPathSumUtil 的顶级调用。值 13 返回到 maxPathSumUtil 的另一个执行上下文,其中 root 是节点 10。然后 -- 在进行另一个递归调用之后(root 等于节点 2),这个顶层执行函数maxPathSumUtil 将:

  • res设置为25(节点10以下两个叶子之间的最大路径)
  • 返回 23(从节点 10 到其叶子之一的最大路径)

此顶级调用是从maxPathSum 内部进行的,忽略maxPathSumUntil 返回的值。 它只取res (25) 的值,并返回that

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

【讨论】:

  • 谢谢先生,你能告诉我Line: Problem是如何工作的吗,因为在执行递归语句后,返回语句也被执行
  • 是的,这到底是什么问题?
  • 先生,我已经编辑了我的问题。请看一看。
  • 查看我的答案。
  • lsroot 为 10 的执行上下文中变为 13。当从节点 8 上的更深调用返回时会发生这种情况:ls=maxPathSumUtil(root.left)。当然,该函数调用通过return ... 返回,这就是ls 获取该返回值的方式。
【解决方案2】:

在每个节点上,我们必须检查该节点的左右子节点是否导致最大路径。但是当我们返回时,我们需要根据最大值返回左路径或右路径。 我们以这棵树为例:

         10
       /   \
     8      2
   /  \
 3     5

这里,递归调用后,ls变成3,rs变成5,res变成ls+rs+root.data,也就是3+5+8=16,所以res(result)会更新为16,然后返回将是 max(11,13),即 13。现在这个 13 的值将被节点 10 用作 ls(left value)。

【讨论】:

    猜你喜欢
    • 2011-03-08
    • 1970-01-01
    • 2012-06-21
    • 2017-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2021-12-18
    相关资源
    最近更新 更多