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

寻求二叉树中不相交叶到叶路径最大和的解决方案及学习资料

二叉树不相交叶到叶路径最大总和问题解决方案

问题分析

结合你提供的示例附图,你的需求是找到二叉树中不共享边的叶到叶路径集合,使得路径节点总和最大,且路径分叉的根节点不被计入总和。当前你的代码逻辑存在两个核心问题:

  • 只考虑了单条路径或单个节点下的两条子路径组合,没有处理多组不相交路径的情况
  • 错误地将当前节点值加入了单路径计算,不符合“分叉根节点不计入总和”的规则

你的示例附图:

你尝试的代码如下:

int depth(struct node *root, int *res)
{
    if(root == NULL) return 0;
    
    int l = depth(root->left, res);
    int r = depth(root->right, res);
    
    int max_single_best_Way = max(l+root->data, r+root->data);

    int max_root = l+r;
    
    int maximum = max(max_single_best_Way, max_root);
    *res = max(*res, maximum);

    return maximum;
}

算法思路建议

核心思路:后序遍历+树形DP

我们需要在遍历每个节点时维护两个关键状态,从叶子节点向上递归处理:

  • 当前节点到下方叶子的最大单路径和:不计入当前节点值,用于向上传递可选路径
  • 全局最大不相交路径总和:记录遍历过程中所有可行的不相交叶到叶路径组合的最大值

具体执行步骤:

  1. 叶子节点:单路径和为0(无后续节点),无法形成叶到叶路径,对全局总和无贡献
  2. 非叶子节点:
    • 递归计算左右子树的单路径和
    • 若同时存在左右子树,可形成一条叶到叶路径,其和为左右单路径和之和,直接更新全局最大值
    • 当前节点的单路径和取左右子树单路径和的较大值(只能选择一条路径向上传递,避免边共享)
    • 全局最大值还要对比左右子树各自的最大总和,确保不遗漏子树内部的最优解

修正后的可运行代码

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

struct node {
    int data;
    struct node* left;
    struct node* right;
};

struct node* newNode(int data) {
    struct node* node = (struct node*)malloc(sizeof(struct node));
    node->data = data;
    node->left = NULL;
    node->right = NULL;
    return node;
}

int max(int a, int b) {
    return (a > b) ? a : b;
}

// 返回当前节点到叶子的最大单路径和,同时更新全局最大总和
int traverse(struct node* root, int* global_max) {
    if (root == NULL) return 0;
    // 叶子节点:无后续路径,单路径和为0
    if (root->left == NULL && root->right == NULL) return 0;

    int left_single = traverse(root->left, global_max);
    int right_single = traverse(root->right, global_max);

    // 左右子树都存在时,计算当前叶到叶路径和并更新全局最大值
    if (root->left != NULL && root->right != NULL) {
        int current_sum = left_single + right_single;
        *global_max = max(*global_max, current_sum);
        // 返回较大的单路径,用于上层节点组合
        return max(left_single, right_single);
    }

    // 只有单侧子树时,直接返回对应子树的单路径和
    return root->left != NULL ? left_single : right_single;
}

int maxDisjointLeafPathsSum(struct node* root) {
    int global_max = INT_MIN;
    traverse(root, &global_max);
    // 处理无叶到叶路径的情况(如单节点树)
    return global_max == INT_MIN ? 0 : global_max;
}

// 测试示例
int main() {
    struct node* root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->left = newNode(4);
    root->left->right = newNode(5);
    root->right->left = newNode(6);
    root->right->right = newNode(7);

    printf("最大不相交叶到叶路径总和:%d\n", maxDisjointLeafPathsSum(root));
    return 0;
}

关键注意事项

  • 路径不共享边:每个边只能属于一条路径,因此选择节点的左右子路径组合后,只能向上传递其中一条路径的信息
  • 分叉根节点不计入总和:路径和仅包含叶子到分叉节点之间的子节点值,分叉节点本身不参与计算

学习资料推荐

  • 二叉树后序遍历应用:重点掌握后序遍历在子树状态收集与合并中的核心逻辑,这是树形问题的基础
  • 树形DP入门:学习树形动态规划的通用框架,掌握如何为每个节点定义状态并进行状态转移
  • 路径和系列问题:先解决「二叉树最大叶到叶路径和」「二叉树最大路径和」等基础问题,再进阶到多路径不相交的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 21:10:29