Binary Tree Maximum Path Sum

Question

Problem Statement

Given a binary tree, find the maximum path sum.

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

Example

Given the below binary tree:

  1
 / \
2   3

return 6.

题解1 - 递归中仅返回子树路径长度

如题目右侧的四颗半五角星所示,本题属于中等偏难的那一类题。题目很短,要求返回最大路径和。咋看一下感觉使用递归应该很快就能搞定,实则不然,因为从题目来看路径和中不一定包含根节点!也就是说可以起止于树中任一连通节点。

弄懂题意后我们就来剖析剖析,本着由简入难的原则,我们先来分析若路径和包含根节点,如何才能使其路径和达到最大呢?选定根节点后,路径和中必然包含有根节点的值,剩下的部分则为左子树和右子树,要使路径和最大,则必然要使左子树和右子树中的路径长度都取最大。

Warning 注意区分包含根节点的路径和(题目要的答案)和左子树/右子树部分的路径长度(答案的一个组成部分)。路径和=根节点+左子树路径长度+右子树路径长度

       -10
       /  \
      2    -3
     / \   / \
    3   4 5   7

如上所示,包含根节点-10的路径和组成的节点应为4 -> 2 -> -10 <- -3 <- 7, 对于左子树而言,其可能的路径组成节点为3 -> 24 -> 2, 而不是像根节点的路径和那样为3 -> 2 <- 4. 这种差异也就造成了我们不能很愉快地使用递归来求得最大路径和。

我们使用分治的思想来分析路径和/左子树/右子树,设 $$f(root)$$ 为root的子树到root节点(含)路径长度的最大值,那么我们有

$$f(root) = root->val + \max (f(root->left), ~f(root->right))$$

递归模型已初步建立起来,接下来就是分析如何将左右子树的路径长度和最终题目要求的「路径和」挂钩。设 $$g(root)$$ 为当「路径和」中根节点为root时的值,那么我们有

$$g(root) = root->val + f(root->left) + f(root->right)$$

顺着这个思路,我们可以遍历树中的每一个节点求得 $$g(node)$$ 的值,输出最大值即可。如果不采取任何记忆化存储的措施,其时间复杂度必然是指数级别的。嗯,先来看看这个思路的具体实现,后续再对其进行优化。遍历节点我们使用递归版的前序遍历,求单边路径长度采用递归。

题解2 - 递归中同时返回子树路径长度和路径和

# Definition for a  binary tree node
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    # @param root, a tree node
    # @return an integer
    def maxsum(self, root):
        if root == None: return 0
        sum = root.val
        lmax = 0; rmax = 0
        if root.left:
            lmax = self.maxsum(root.left)
            if lmax > 0:
                sum += lmax
        if root.right:
            rmax = self.maxsum(root.right)
            if rmax > 0:
                sum += rmax
        if sum > Solution.max: Solution.max = sum
        return max(root.val, max(root.val + lmax, root.val + rmax))

    def maxPathSum(self, root):
        Solution.max = -10000000
        if root == None: return 0
        self.maxsum(root)
        return Solution.max
"""
Definition of TreeNode:
class TreeNode:
    def __init__(self, val):
        this.val = val
        this.left, this.right = None, None
"""
class Solution:
    """
    @param root: The root of binary tree.
    @return: An integer
    """
    def maxPathSum(self, root):
        maxSum, _ = self.maxPathHelper(root)
        return maxSum

    def maxPathHelper(self, root):
        if root is None:
            return -sys.maxint, 0

        left = self.maxPathHelper(root.left)
        right = self.maxPathHelper(root.right)
        maxpath = max(left[0], right[0], root.val + left[1] + right[1])
        single = max(left[1] + root.val, right[1] + root.val, 0)

        return maxpath, single

results matching ""

    No results matching ""