自学内容网 自学内容网

LeetCode 热题 100_二叉树中的最大路径和(50_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 * 104]
-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。

代码实现

代码实现(思路一(深度优先搜索)):
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;
    }
};
以思路一为例进行调试
#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 热题 100_二叉树中的最大路径和(50_124)原题链接
欢迎大家和我沟通交流(✿◠‿◠)


原文地址:https://blog.csdn.net/huayimenghan/article/details/145126781

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!