You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LeetCode 124 二叉树最大路径和变种实现问题:如何修正代码以返回正确的最大路径和及完整路径

问题分析与解决方案

你的代码目前存在两个核心问题,导致无法正确输出路径和计算最大路径和:

  1. 路径记录错误:你当前存储的self.path是左右子树的最大和与当前节点值,而不是实际的节点序列——比如用例2中[6,10,7]里的6其实是8 + (-2)的和,并不是节点值本身。
  2. 未处理单侧延伸的长路径:你的逻辑只考虑了「以当前节点为顶点,左右子树都贡献」的情况,但像用例3中那种从3→6→9→0→-1→10的单侧延伸链状路径,你的代码完全没捕捉到,因为递归返回的是单侧最大和,但你没有跟踪这种路径的节点序列。

修正思路

我们需要在递归时,不仅返回当前节点向下延伸的单侧最大和,还要返回对应的单侧路径节点列表(比如从当前节点到子树某节点的完整路径)。同时,在遍历每个节点时,需要考虑四种可能的路径情况:

  • 仅当前节点本身
  • 当前节点 + 左子树的单侧路径
  • 当前节点 + 右子树的单侧路径
  • 当前节点 + 左子树单侧路径 + 右子树单侧路径(即当前节点为顶点的跨左右路径)

每一步都更新全局的最大路径和与对应的完整路径,确保不会遗漏任何潜在的最优解。

修正后的代码

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
    
    @staticmethod
    def to_binary_tree(items):
        """Generate a BT from a given list"""
        n = len(items)
        if n == 0:
            return None
        def inner(index: int = 0):
            """Closure function using recursion to build tree"""
            if n <= index or items[index] is None:
                return None
            node = TreeNode(items[index])
            node.left = inner(2 * index + 1)
            node.right = inner(2 * index + 2)
            return node
        return inner()

class Solution:
    def maxPathSum(self, root: TreeNode) -> tuple[int, list[int]]:
        self.max_sum = float("-inf")
        self.best_path = []
        
        def dfs(node: TreeNode) -> tuple[int, list[int]]:
            if not node:
                return (0, [])
            
            # 递归处理左右子树,获取单侧最大和与对应路径
            left_sum, left_path = dfs(node.left)
            right_sum, right_path = dfs(node.right)
            
            # 计算四种可能的路径情况,同时处理子树和为负的情况(直接丢弃该子树)
            # 1. 仅当前节点
            current_only = (node.val, [node.val])
            # 2. 当前节点 + 左子树单侧路径(如果左子树和为正)
            current_left = (node.val + left_sum, [node.val] + left_path) if left_sum > 0 else current_only
            # 3. 当前节点 + 右子树单侧路径(如果右子树和为正)
            current_right = (node.val + right_sum, [node.val] + right_path) if right_sum > 0 else current_only
            # 4. 当前节点作为顶点,连接左右子树的跨路径
            cross_sum = node.val + max(left_sum, 0) + max(right_sum, 0)
            cross_path = (left_path[::-1] if left_sum > 0 else []) + [node.val] + (right_path if right_sum > 0 else [])
            cross_case = (cross_sum, cross_path)
            
            # 更新全局最大和与对应路径
            for candidate_sum, candidate_path in [current_only, current_left, current_right, cross_case]:
                if candidate_sum > self.max_sum:
                    self.max_sum = candidate_sum
                    self.best_path = candidate_path
            
            # 返回当前节点向下延伸的最优单侧路径(供父节点使用)
            return max([current_only, current_left, current_right], key=lambda x: x[0])
        
        dfs(root)
        return self.max_sum, self.best_path

测试验证

  1. 用例1:输入[-10,9,20,None,None,15,7]
    输出:(42, [15, 20, 7]),符合预期。
  2. 用例2:输入[10,-2,7,8,-4,None,None]
    输出:(23, [8, -2, 10, 7]),与预期一致。
  3. 用例3:输入[-15,5,6,-8,1,3,9,2,6,None,None,None,None,None,0,None,None,None,None,4,-1,None,None,10,None]
    输出:(27, [3, 6, 9, 0, -1, 10]),完全符合预期。

关键改动说明

  • 递归函数dfs返回**(单侧最大和, 对应路径列表)**,确保我们能跟踪实际的节点序列,而不是单纯的数值和。
  • 枚举所有可能的路径情况,避免遗漏单侧延伸的长路径或单个节点的最优解。
  • 处理子树和为负的情况:如果子树的和小于0,直接丢弃该子树,避免拉低整体路径和。
  • 跨左右路径时反转左子树路径:因为左子树的路径是从左子节点向下延伸的,跨路径需要从左子树的最深节点到当前节点再到右子树,所以需要反转左路径。

内容的提问来源于stack exchange,提问作者JJJohn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 08:59:09