题目描述
二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。路径和 是路径中各节点值的总和。给你一个二叉树的根节点 root
,返回其 最大路径和
输入:root = [1,2,3] 输出:6 解释:最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6
输入:root = [-10,9,20,null,null,15,7] 输出:42 解释:最优路径是 15 -> 20 -> 7 ,路径和为 15 + 20 + 7 = 42
题解
可以看到此题不同于一般的最大路径问题,因为可以从任意节点出发到任意节点结束并且只需要无重复节点和相邻节点存在直连边。所以从问题出发,以某个节点为根的子树,这个子树的贡献有两点:1.这颗子树中和最大路径和(服务最终结果) 2.经过这颗子树的根节点的路径最大路径和(服务这颗子树外其他节点)。例如我们看值为20的这颗子树,它首先能贡献在这颗子树中最大路径为15->20->7,和为42。同时它能向自己的父亲节点贡献20->15 = 20 + 15 = 35 的经过根节点的最大路径和。所以,想到了递归遍历,首先计算这颗子树自己的贡献1(需要利用这颗子树的左右子树的贡献2),然后向上层调用者返回这颗子树自己贡献2。这样层层遍历,找到最大的路径和。
代码如下
/**
* 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:
int maxPathSum(TreeNode* root) {
int output= INT_MIN;
searchroad(root, output);
return output;
}
int searchroad(TreeNode *node, int& output){
if(node == nullptr){
return 0;
}
int leftroad = searchroad(node -> left, output);
int rightroad = searchroad(node -> right, output);
output = max(output, leftroad + node -> val + rightroad);
output = max(output, leftroad + node -> val);
output = max(output, rightroad + node -> val);
output = max(output, node -> val);
return max(max(node -> val + leftroad, node -> val + rightroad), node -> val);
}
};