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

Python循环破坏二叉树最大路径和递归算法问题排查

二叉树最大路径和:全负节点边缘用例的问题与修复

问题背景

处理二叉树最大路径和问题时,针对全负节点的边缘用例,添加的一段for循环代码出现互斥问题:

  • 注释循环时,除全负节点用例返回错误的0外,其余用例结果正确;
  • 不注释循环时,仅全负节点用例正确,其余所有用例结果错误。

原始代码

class Node():
    def __init__(self, value, binList):
        self.value = value
        self.left_child = None
        self.right_child = None
        self.binList = binList
        
def binTree(binList, i=0):
    if i < len(binList):
        value = binList[i]
        if value == None:
            return
        node = Node(value, binList)
        node.left_child = binTree(binList, i * 2 + 1)
        node.right_child = binTree(binList, i * 2 + 2)
        return node

def pathFinder(root):
    neg_max = float("-inf")
    # for x in root.binList:
    #     if x != None:
    #         neg_max = max(neg_max, x)
    # if neg_max < 0 and neg_max != float("-inf"):
    #     return neg_max

    try:
        left_sum = max(0, pathFinder(root.left_child))
        right_sum = max(0, pathFinder(root.right_child))
        current_path_sum = root.value + left_sum + right_sum
        return max(current_path_sum, max(left_sum, right_sum))
    except:
        return 0

# 测试用例
print("expected 6, output:",pathFinder(binTree([1,2,3])))
print("expected 42, output:",pathFinder(binTree([-10,9,20,None,None,15,7])))
print("expected 35, output:",pathFinder(binTree([-10,-9,20,None,None,15,-7])))
print("expected 20, output:",pathFinder(binTree([-10,-9,-20,None,None,15,-7,None,None,None,None,5])))
print("expected -1, output:",pathFinder(binTree([-1,-2,-3])))

两种输出情况

  • 注释循环时输出:
expected 6, output: 6
expected 42, output: 42
expected 35, output: 35
expected 20, output: 20
expected -1, output: 0
  • 不注释循环时输出:
expected 6, output: 1
expected 42, output: 20
expected 35, output: 20
expected 20, output: 0
expected -1, output: -1

错误原因分析

  1. 全局状态破坏递归局部性:每个Node实例都存储了完整的输入列表binList,导致递归的每一层都会遍历整个树的所有节点。当树不全是负数时,循环不会触发返回,但递归逻辑本身存在缺陷,导致后续计算完全错误。
  2. 递归逻辑混淆核心概念:原始pathFinder函数错误地将「子树内部的最大路径和」和「向上传递的路径和」混为一谈,返回值既不是正确的局部最大和,也不是能传递给父节点的有效路径和。比如处理[1,2,3]时,子节点的递归返回值错误,导致根节点计算出的路径和仅为1。
  3. 异常处理滥用:用try-except捕获空节点的访问异常并直接返回0,在全负场景下会错误舍弃负节点的贡献,导致返回0而非最大的负数。

修复方案

核心思路

  • 移除全局列表的存储,让递归仅关注当前节点的局部状态;
  • 拆分递归逻辑:用一个变量跟踪全局最大路径和,递归函数仅返回当前节点能向上传递的有效路径和;
  • 自然处理全负场景:当所有子树贡献为负时,仅保留当前节点的值作为向上传递的路径和,全局变量会自动记录最大的负数。

修正后的代码

class Node():
    def __init__(self, value):
        self.value = value
        self.left_child = None
        self.right_child = None
        
def binTree(binList, i=0):
    if i < len(binList):
        value = binList[i]
        if value is None:
            return None
        node = Node(value)
        node.left_child = binTree(binList, i * 2 + 1)
        node.right_child = binTree(binList, i * 2 + 2)
        return node

def maxPathSum(root):
    max_sum = float("-inf")
    
    def dfs(node):
        nonlocal max_sum
        if not node:
            return 0
        # 计算左右子树的有效贡献(负贡献则舍弃,取0)
        left_contribution = max(dfs(node.left_child), 0)
        right_contribution = max(dfs(node.right_child), 0)
        # 更新全局最大路径和(当前节点作为路径顶点的情况)
        current_path_sum = node.value + left_contribution + right_contribution
        if current_path_sum > max_sum:
            max_sum = current_path_sum
        # 返回当前节点能向上传递的最大路径和(只能选左或右分支+当前节点)
        return node.value + max(left_contribution, right_contribution)
    
    dfs(root)
    return max_sum

# 测试用例验证
print("expected 6, output:", maxPathSum(binTree([1,2,3])))
print("expected 42, output:", maxPathSum(binTree([-10,9,20,None,None,15,7])))
print("expected 35, output:", maxPathSum(binTree([-10,-9,20,None,None,15,-7])))
print("expected 20, output:", maxPathSum(binTree([-10,-9,-20,None,None,15,-7,None,None,None,None,5])))
print("expected -1, output:", maxPathSum(binTree([-1,-2,-3])))

修正点说明

  • 移除Node类中的binList属性,避免递归中访问全局数据;
  • 使用嵌套的dfs函数实现递归,通过nonlocal变量max_sum跟踪全局最大路径和;
  • dfs函数返回当前节点能向上传递的最大路径和,确保父节点能正确计算包含当前节点的路径;
  • 当处理全负节点时,左右子树的贡献会被视为0,current_path_sum等于当前节点的值,max_sum会记录所有节点中的最大值(即最大的负数)。

测试结果

修正后的代码所有测试用例均输出正确结果:

expected 6, output: 6
expected 42, output: 42
expected 35, output: 35
expected 20, output: 20
expected -1, output: -1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 08:37:30