LeetCode 面试经典 150_二叉树_二叉树中的最大路径和(77_124_C++_困难)(DFS)

LeetCode 面试经典 150_二叉树_二叉树中的最大路径和(77_124_C++_困难)

题目描述:

二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。

路径和 是路径中各节点值的总和。

给你一个二叉树的根节点 root ,返回其 最大路径和

输入输出样例:

示例 1:

输入 :root = 1,2,3
输出 :6
解释:最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6

示例 2:

输入 :root = -10,9,20,null,null,15,7
输出 :42
解释:最优路径是 15 -> 20 -> 7 ,路径和为 15 + 20 + 7 = 42

提示:

树中节点数目范围是 1, 3 \* 10^4^

-1000 <= Node.val <= 1000

题解:

解题思路:

思路一(深度优先搜索):

1、计算一个结点向下的最大路径和,就是计算左右子树的最大路径相加,再加上本结点的值(当然左右子树最大路径为负数时无需加左右子树)。为了进行上述的计算,我们需要从递归返回时进行操作,即从叶结点开始向上计算,这样我们就能方便的得到每个结点左右子树的最大路径和,进而得到当前结点的最大路径和。在这个过程中采用一个全局变量存储树中的最大路径和。

: 假设一个结点为root,左子树的最大路径和为leftSum,右子树的最大路径和为rightSum。

则当前结点的最大路径和为(root->val+leftSum+rightSum)这里leftSum和rightSum均大于等于0。

递归返回时我们需要返回:当前结点的值root->val+max(leftSum,rightSum)。这里leftSum和rightSum均大于等于0。(因为我们返回的是一条一直向下的路径)

2、复杂度分析:

① 时间复杂度:O(n),n代表二叉树中的结点数,需要遍历整个二叉树一次。

② 空间复杂度:O(n),n代表二叉树中的结点数,最坏情况下递归函数栈的深度是n。

代码实现

代码实现(思路一(深度优先搜索)):
cpp 复制代码
class Solution
{
private:
    //maxSum存储二叉树的最大路径
    int maxSum=INT32_MIN;
    
    //递归的求解最大路径
    int dfs(TreeNode *root){
        if (root==nullptr) return 0;

        //左子树向下的路径最大值
        int leftSum=max(dfs(root->left),0) ;
        //右子树向下的路径最大值
        int rightSum=max(dfs(root->right),0);

        //当前结点最大路径和
        int currentSum=root->val+leftSum+rightSum;
        //更新最大路径和
        maxSum=max(currentSum,maxSum);

        //返回当前结点左右子树中较大的路径
        return root->val+max(leftSum,rightSum);       

    }

public:
    //计算一个结点向下的最大路径,就是计算左右子树的最大路径相加再加上本结点
    //如果左右子树的最大路径为<0则不进行累加
    int maxPathSum(TreeNode *root){
        dfs(root);
        return maxSum;
    }
};
以思路一为例进行调试
cpp 复制代码
#include<iostream>
#include <vector>
#include <queue>
using namespace std;

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) {}
};

//通过数组创建二叉树,-1代表nullptr
TreeNode *createTree(const vector<int> &nums){
    if (nums.empty()) return nullptr;
    queue<TreeNode *> Q;
    TreeNode *root=new TreeNode(nums[0]);
    Q.push(root);
    int i=1;
    while (i<nums.size())
    {
        TreeNode *node=Q.front();
        Q.pop();
        if (nums[i]!=-1 )
        {
            node->left=new TreeNode(nums[i]);
        }
        ++i;
        if (nums[i]!=-1 && i<nums.size())
        {
            node->right=new TreeNode(nums[i]);
        }
        ++i;
    }
    return root;
    
}

//中序遍历输出二叉树,验证二叉树创建是否正确
void inorder(TreeNode *root){
    if(root==nullptr) return;
    inorder(root->left);
    cout<<root->val<<" ";
    inorder(root->right);
}

class Solution
{
private:
    //maxSum存储二叉树的最大路径
    int maxSum=INT32_MIN;
    
    //递归的求解最大路径
    int dfs(TreeNode *root){
        if (root==nullptr) return 0;

        //左子树向下的路径最大值
        int leftSum=max(dfs(root->left),0) ;
        //右子树向下的路径最大值
        int rightSum=max(dfs(root->right),0);

        //当前结点最大路径和
        int currentSum=root->val+leftSum+rightSum;
        //更新最大路径和
        maxSum=max(currentSum,maxSum);

        //返回当前结点左右子树中较大的路径
        return root->val+max(leftSum,rightSum);       

    }

public:
    //计算一个结点向下的最大路径,就是计算左右子树的最大路径相加再加上本结点
    //如果左右子树的最大路径为<0则不进行累加
    int maxPathSum(TreeNode *root){
        dfs(root);
        return maxSum;
    }
};

int main(int argc, char const *argv[])
{
    vector<int> nums={1,2,3};

    //通过数组创建二叉树,-1代表nullptr
    TreeNode *root= createTree(nums);
    
    //中序遍历验证二叉树创建是否正确
    // inorder(root);

    //计算二叉树中最大路径和并输出
    Solution s;
    cout<<s.maxPathSum(root);

    return 0;
}

LeetCode 面试经典 150_二叉树_二叉树中的最大路径和(77_124)原题链接

欢迎大家和我沟通交流(✿◠‿◠)

相关推荐
Forever Nore1 小时前
LeetCode 14 最长公共前缀 - 纵向扫描
linux·服务器·leetcode
圣保罗的大教堂1 小时前
leetcode 3090. 每个字符最多出现两次的最长子字符串 简单
leetcode
djjjx.1 小时前
【 C++ 】多态
开发语言·c++·多态
艾莉丝努力练剑1 小时前
【QT:解决问题】Qt5Core.dll:无法定位程序输入点
java·开发语言·qt·学习·面试
鸿芯微控科技2 小时前
MFC关断后还有流量怎么办?零流量、阀门泄漏、压差与Python分析
c++·python·mfc·质量流量控制器·关断泄漏·零流量测试
ShineWinsu13 小时前
对于C++:C++11中lambda、function、bind的解析
c++·面试·笔试·开发·lambda·bind·function
码匠许师傅13 小时前
【C++ 面试真题】聊聊 C++ 的拷贝构造与拷贝赋值
java·c++·面试
旖旎夜光14 小时前
LeetCode 3:无重复字符的最长子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
汉字萌萌哒14 小时前
2024CSP-J入门级C++真题详解
开发语言·c++
sakiko_15 小时前
OC学习笔记-面试题
面试·objective-c