LeetCode 124 —— 二叉树中的最大路径和

阅读目录

    • [1. 题目](#1. 题目)
    • [2. 解题思路](#2. 解题思路)
    • [3. 代码实现](#3. 代码实现)

1. 题目

2. 解题思路

二叉树的问题首先我们要想想是否能用递归来解决,本题也不例外,而递归的关键是找到子问题。

我们首先来看看一棵最简单的树,也就是示例 1。这样的一棵树总共有六条路径,分别是:根节点、左节点-根节点、右节点-根节点、左节点、右节点、左节点-根节点-右节点,我们用一个大小为 6 的数组 rootSum 来分别表示这六条路径的路径和,那么所求的最大路径和即为 rootSum 的最大值。

需要注意,当某一个节点为空的时候,比如左节点为空,那么左节点-根节点路径和为根节点的值,左节点贡献值为 0。而单独左节点的路径不存在,路径和应该设置为一个极大的负值

接下来,我们再考虑一个更复杂的树,这棵树的根节点有左右两棵子树,每一棵子树都是类似上面示例 1 的一棵树。那么,我们可以很容易地得到左右子树的路径和数组 leftSumrightSum ,接下来,我们要做的就是如何根据这两个数组得到整棵树的路径和数组 rootSum

rootSum 仍然有 6 条路径,其中:

  • 只有一个根节点的路径,rootSum[0]=root->val
  • 左节点-根节点的路径,这时候由于左节点是一棵子树,所以,只有包含子树中根节点的路径才能继续和当前的根节点组成新的路径 ,也就是子树的前三条路径,然后我们取其中最大的一条即可,rootSum[1]=root->val + max(leftSum[0:3))
  • 右节点-根节点的路径,这个和上面的类似,rootSum[2]=root->val + max(rightSum[0:3))
  • 左节点,也即是单独左子树组成的最大路径,rootSum[3]=max(leftSum[0:6))
  • 右节点,也即是单独右子树组成的最大路径,rootSum[4]=max(rightSum[0:6))
  • 左节点-根节点-右节点,也就是左子树的路径包含左子树的根节点,右子树的路径包含右子树的根节点,rootSum[5]=max(leftSum[0:3))+ root->val + max(rightSum[0:3))

时间复杂度为 O ( n ) O(n) O(n), n n n 代表节点总数,每个节点都需要进行遍历一次,空间复杂度为 O ( n ) O(n) O(n),每个节点都需要存储 6 个状态值。

3. 代码实现

c 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> getNodePathSum(TreeNode* root) {
        int leftRootSum = 0, leftMaxSum = -10000;
        if (root->left != nullptr) {
            vector<int> leftSum = getNodePathSum(root->left);
            leftRootSum = *std::max_element(leftSum.begin(), leftSum.begin() + 3);
            leftMaxSum = *std::max_element(leftSum.begin(), leftSum.end());
        }
        int rightRootSum = 0, rightMaxSum = -10000;
        if (root->right != nullptr) {
            vector<int> rightSum = getNodePathSum(root->right);
            rightRootSum = *std::max_element(rightSum.begin(), rightSum.begin() + 3);
            rightMaxSum = *std::max_element(rightSum.begin(), rightSum.end());
        }
        vector<int> rootSum(6, 0);
        rootSum[0] = root->val;
        rootSum[1] = leftRootSum + root->val;
        rootSum[2] = rightRootSum + root->val;
        rootSum[3] = leftMaxSum;
        rootSum[4] = rightMaxSum;
        rootSum[5] = leftRootSum + root->val + rightRootSum;
        return rootSum;
    }

    int maxPathSum(TreeNode* root) {
        vector<int> sum = getNodePathSum(root);
        return *std::max_element(sum.begin(), sum.end());
    }
};
相关推荐
寂柒几秒前
C++——模拟实现stack和queue
开发语言·c++·算法·list
熬夜学编程的小王20 分钟前
C++类与对象深度解析(一):从抽象到实践的全面入门指南
c++·git·算法
CV工程师小林22 分钟前
【算法】DFS 系列之 穷举/暴搜/深搜/回溯/剪枝(下篇)
数据结构·c++·算法·leetcode·深度优先·剪枝
Dylanioucn25 分钟前
【分布式微服务云原生】掌握 Redis Cluster架构解析、动态扩展原理以及哈希槽分片算法
算法·云原生·架构
繁依Fanyi34 分钟前
旅游心动盲盒:开启个性化旅行新体验
java·服务器·python·算法·eclipse·tomcat·旅游
罔闻_spider44 分钟前
爬虫prc技术----小红书爬取解决xs
爬虫·python·算法·机器学习·自然语言处理·中文分词
OLDERHARD1 小时前
Java - LeetCode面试经典150题 - 矩阵 (四)
java·leetcode·面试
Themberfue1 小时前
基础算法之双指针--Java实现(下)--LeetCode题解:有效三角形的个数-查找总价格为目标值的两个商品-三数之和-四数之和
java·开发语言·学习·算法·leetcode·双指针
陈序缘2 小时前
LeetCode讲解篇之322. 零钱兑换
算法·leetcode·职场和发展
-$_$-2 小时前
【LeetCode HOT 100】详细题解之二叉树篇
数据结构·算法·leetcode