二叉树中的最大路径和

该博客探讨了如何找到二叉树中的最大路径和,提出以最高节点为中心的四种可能的最大路径情况,并通过递归实现算法。通过遍历每个节点并计算以该节点为起点的单向路径最大值,最终得到整个二叉树的最大路径和。
题目描述:给出一棵二叉树,寻找一条路径使其路径和最大,路径可以在任一节点中开始和结束(路径和为两个节点之间所在路径上的节点权值之和)
样例:给出一棵二叉树:

        1
      /    \
    2      3

返回 6


这里面有一个默认的事实,那就是不管这个路径在哪,他都肯定有一个最高的节点。我们不妨可以设这个节点为A,以A为最高节点的路径的最大长度是多少呢?

A有左右两个孩子(当然孩子可以是空),以每个孩子为起点,向下延伸,可以得到很多条单向的路径,这其中当然有一个最大路径。我们将以左孩子为起点的最大路径的值记为left_val,将以右孩子为起点的最大路径的值记为right_val,显然以A为最高点的最大路径只可能有以下四种情况:

1. 若left_val < 0, 且right_val < 0, 那最大路径为A节点本身:maxPathSum(A) = A.val

2. 若left_val > 0, 且right_val < 0, 那最大路径为A节点和以A的左孩子为起点的最大路径:maxPathSum(A) = A.val + left_val

3. 若left_val < 0, 且right_val > 0, 那最大路径为A节点和以A的右孩子为起点的最大路径:maxPathSum(A) = A.val + right_val

3. 若left_val > 0, 且right_val > 0, 那最大路径为A节点和以A的左、右孩子为起点的最大路径三者的联合:maxPathSum(A) = A.val + left_val + right_val


综上,以A为最高点的最大路径是上面四种情况的最大值。那我们遍历二叉树的所有节点,求以每个节点为最高节点的最大路径的最大值即可。

当然,为方便编程,我们可以另写一个函数,求取以每个节点为起点的单向路径的最大值。这个函数显然可以用递归解决。


代码如下:

"""
Definition of TreeNode:
class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left, self.right = None, None
"""
class Solution:
    """
    @param root: The root of binary tree.
    @return: An integer
    """
    def maxPathSum(self, root):
        if root is None:
            return 0
        result = [root.val]
        self.helper(root, result)
        return result[0]

    def helper(self, root, result):
        if root is None:
            return 0
        # 由左孩子开始的最长路径
        left_val = self.helper(root.left, result)
        # 由右孩子开始的最长路径
        right_val = self.helper(root.right, result)
        # 计算以root为最高点的最长路径的长度,并和原先的最大值比较
        result[0] = max(result[0], max(left_val, 0) + max(right_val, 0) + root.val)
        # 返回以root为起点的最长路径的长度
        return max(root.val + left_val, root.val + right_val, root.val)
        # write your code here

我把递归求解以某个节点为起点的单向路径的函数写成了代码中的helper()函数,为节省代码量,把以某个节点为最高点的最大路径的比较问题也嵌入了这个函数。代码28行做的就是这件事情。为了对所有节点进行比较,我让helper()函数的参数里面的result作为一个只有一个元素的列表记录以某个节点为最高点的路径的最大值,之所以用了一个只有一个元素的列表,而不是直接用一个整型变量,是因为用整型变量会导致result成为局部变量,不随程序进行发生改变。用列表则方便很多。


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值