博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法题解:用DFS(递归)寻找树中的最大权值路径
阅读量:6625 次
发布时间:2019-06-25

本文共 1672 字,大约阅读时间需要 5 分钟。

题目分析

题目链接:

不难分析出,最大的路径是“^型”的,从一个最高点向下延伸的两条路径组成一个“^型”路径。注意这个“最高点”不一定是树的根。

并且,这两条路径必定分别经过左右子节点,并且是向下路径中权值最大的。
由于每个节点都有可能是“最高点”,因此对于每个节点(可以用DFS/BFS遍历每个节点),我们都要计算出以该节点为“最高点”的最大“^型”路径;。为了计算出该值,我们要先得到经过左子节点的最长向下路径经过右子节点的最长向下路径(这两个值可以用DFS得到),两者相加,再加上该节点本身的权值,就得到了以该节点为“最高点”的最大“^型”路径;

这时如果不注意可能会出现严重的性能问题:两层DFS嵌套。第一层DFS用于遍历每个节点,并假设这个节点为“^型”路径的最高点;对于每个节点,又会进行第二层DFS:用于计算两个最长的向下路径。

两层DFS嵌套会大大影响计算时间,我们应该合并两次DFS。注意到DFS只不过是一种特殊的递归调用,对于父节点的每个子节点,都进行一次递归调用,每个子节点都遍历完毕(子节点的调用堆栈经历装载、弹出)以后,返回到父节点的调用堆栈(如果父节点不需要进行后续的计算,则父节点的调用堆栈弹出)。我们如果在第一次遍历中就计算出经过子节点的最长的向下路径,并返回给父节点的调用堆栈,父节点就能直接计算出经过左/右子节点的最长的向下路径,从而避免第二层的递归调用。

代码实现

/** * Definition for a binary tree node. * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution{  private:    // 存放已经找到的最大路径权值    int result;  public:    int maxPathSum(TreeNode *root)    {        this->result = INT_MIN;        calculateMaxPathDown(root);        return this->result;    }    // 计算从subRoot向下的最大路径权值    // 如果经过subRoot的路径都为负值,则返回0(终止于subRoot的路径权值)    int calculateMaxPathDown(TreeNode *subRoot)    {        if (subRoot == NULL)            return 0;        int leftMaxPathDown = calculateMaxPathDown(subRoot->left);        int rightMaxPathDown = calculateMaxPathDown(subRoot->right);        // 这个语句与本函数的目的无关,但对于得到最终结果至关重要        // 计算以subRoot为最高点的最大 “^型” 路径,将它与已经找到的最大路径比较        this->result = max(leftMaxPathDown + rightMaxPathDown + subRoot->val, this->result);        // 返回从subRoot向下的最大路径权值        return max(0, max(leftMaxPathDown, rightMaxPathDown) + subRoot->val);    }};

由于对每个节点仅仅进行一次递归调用,因此时间复杂度为O(n)

由此可见,在选择递归之前,我们应该仔细思考每次递归调用应该计算什么、返回什么。

转载地址:http://fttpo.baihongyu.com/

你可能感兴趣的文章
Python---装饰器
查看>>
s17data01
查看>>
kubernetes1.9.1 集群
查看>>
java set and get 用法
查看>>
linux笔记1-1
查看>>
dubbo源码分析-负载均衡
查看>>
一统江湖的大前端(3) DOClever——你的postman有点low
查看>>
云栖大会上发布了哪些移动研发新利器?
查看>>
《黑客免杀攻防》读书笔记-软件逆向工程(6) switch-case分支
查看>>
day6作业--游戏人生完善
查看>>
金字塔思维
查看>>
strak组件(10):批量操作
查看>>
thinkphp空控制器的处理
查看>>
Mahout分步式程序开发 聚类Kmeans(转)
查看>>
修改linux最大文件句柄数
查看>>
接口幂等
查看>>
LibreOffice 打开中文乱码
查看>>
FromBottomToTop第十三周项目博客
查看>>
Activity的四种启动模式
查看>>
Centos vsftpd服务器搭建
查看>>