数据结构-----Binary Tree Maximum Path Sum 求二叉树的最大路径和

本文详细解析了BinaryTreeMaximumPathSum问题,通过递归算法寻找二叉树中的最大路径和,介绍了如何从叶节点开始回溯计算,并讨论了在每个节点上选择路径的方法。

Binary Tree Maximum Path Sum 求二叉树的最大路径和
题目要求:Given a binary tree, find the maximum path sum.

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

For example:
Given the below binary tree,

       1
      / \
     2   3
 

Return 6.

思路:我们先来看一个例子,这个树的最远路径和为7+11+4+13

  4
   / \
  11 13
 / \
7   2
树的递归解法一般都是递归到叶节点,然后开始边处理边回溯到根节点。
那么我们就假设此时已经递归到结点7了,那么其没有左右子节点,所以如果以结点7为根结点的子树最大路径和就是7。
然后回溯到结点11,如果以结点11为根结点的子树,我们知道最大路径和为7+11+2=20。
但是当回溯到结点4的时候,对于结点11来说,就不能同时取两条路径了,只能取左路径,或者是右路径,所以当根结点是4的时候,那么结点11只能取其左子结点7,因为7大于2。
所以,对于每个结点来说,我们要知道经过其左子结点的path之和大还是经过右子节点的path之和大。那么我们的递归函数返回值就可以定义为以当前结点为根结点,到叶节点的最大路径之和,然后全局路径最大值放在参数中,用结果res来表示。
在递归函数中,如果当前结点不存在,那么直接返回0。
否则就分别对其左右子节点调用递归函数,由于路径和有可能为负数,而我们当然不希望加上负的路径和,所以我们和0相比,取较大的那个,就是要么不加,加就要加正数。
然后我们来更新全局最大值结果res,就是以左子结点为终点的最大path之和加上以右子结点为终点的最大path之和,还要加上当前结点值,这样就组成了一个条完整的路径。
而我们返回值是取left和right中的较大值加上当前结点值,因为我们返回值的定义是以当前结点为终点的path之和,所以只能取left和right中较大的那个值,而不是两个都要。红色字体部分是转载此链接的,如有问题请留言,谢谢!!!

链接地址:https://www.cnblogs.com/grandyang/p/4280120.html

这是我的思路:     

   0:我们先从根节点开始,开始左子树,右子树的遍历;

         1:我们先遍历左子树,然后每次求取它的路径最大值;

           2:我们接着遍历右子树,然后每次求取它的路径最大值;

           3:每次我们都会 更新sum,求得每次的最大值;

          4:递归函数中,我们每次求得左和右中较大的那个作为返回值,然后进行每次的递归;

关于 sum=INT_MIN;//考虑到负数的情况,从最小的整数开始比较

这个是关于int sum=INT_MIN的详情,及使用:

https://mp.youkuaiyun.com/postedit/81869132

 

下面是我在牛客网oj环境下编译通过的:

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
    int sum;
public:
    int maxPathSum(TreeNode *root) {
         sum=INT_MIN;//考虑到负数的情况,从最小的整数开始比较
        help(root);//从根节点开始递归
        return sum;//返回路径的最大值
    }
    
    int help(TreeNode* root){
        if(!root)   return 0;//递归到叶节点的子节点,返回0
        int left = max(0, help(root->left));//对根节点的左叶节点开始递归
        int right = max(0, help(root->right));//对根节点的右叶节点开始递归
        sum = max(sum, left+right+root->val);//更新现有路径最大值
        return max(left, right)+root->val; 
    }
};


 

 

这段代码是一个经典的 **二叉树中的最大路径**(LeetCode 第124题)的解法,使用了 **DFS(深度优先搜索) + 动态规划思想**。 你提供的代码使用了 C++14 以后的特性,如 **lambda 表达式递归(`this auto&& dfs`)** **立即调用 lambda** 的方式来实现递归 DFS。这种写法在 LeetCode 等 OJ 平台上非常常见,但如果你希望在 **Visual Studio(VS)等标准编译器下编译运行**,这段代码 **可能无法通过编译**,因为 `this auto&& dfs` 这种写法不是标准 C++,而是某些编译器的扩展(比如 GCC 支持,但 MSVC 不支持)。 --- ### ✅ VS 兼容的完整版本(标准 C++17 写法) 下面是可以在 Visual Studio 上正常编译运行的完整版本: ```cpp #include <iostream> #include <algorithm> #include <climits> using namespace std; // Definition for a binary tree node. struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; class Solution { public: int maxPathSum(TreeNode* root) { int ans = INT_MIN; dfs(root, ans); return ans; } private: // 返回以当前节点为结尾的最大路径 int dfs(TreeNode* node, int& ans) { if (!node) return 0; // 递归左右子树 int left_gain = max(dfs(node->left, ans), 0); // 只取正值 int right_gain = max(dfs(node->right, ans), 0); // 当前节点作为最高点,计算路径 int current_path_sum = left_gain + right_gain + node->val; ans = max(ans, current_path_sum); // 返回当前节点的最大(只能选一边) return max(left_gain + node->val, right_gain + node->val); } }; ``` --- ### ✅ 示例 main 函数(用于测试) ```cpp int main() { // 构造一个测试二叉树: // 1 // / \ // 2 3 TreeNode* root = new TreeNode(1); root->left = new TreeNode(2); root->right = new TreeNode(3); Solution sol; cout << "Maximum Path Sum: " << sol.maxPathSum(root) << endl; // 输出 6 // 清理内存 delete root->left; delete root->right; delete root; return 0; } ``` --- ### ✅ VS 编译注意事项: - **不支持 `this auto&& dfs` 写法**(这是 GCC 的扩展)。 - 使用标准的类成员函数或普通函数来递归是兼容性更好的方式。 - 使用 `std::function` 也可以实现递归 lambda,但效率略低。 --- ### ✅ 使用 `std::function` 的版本(兼容性较好) ```cpp #include <functional> int maxPathSum(TreeNode* root) { int ans = INT_MIN; function<int(TreeNode*)> dfs = [&](TreeNode* node) { if (!node) return 0; int l = max(dfs(node->left), 0); int r = max(dfs(node->right), 0); ans = max(ans, l + r + node->val); return max(l, r) + node->val; }; dfs(root); return ans; } ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值