力扣 124. 二叉树中的最大路径和 [1.0,2.0]
路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。
路径和 是路径中各节点值的总和。
给你一个二叉树的根节点 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.0
灵感来自通过110. 平衡二叉树,其中优化方法中,将一整棵树划分为子树,针对每个子树进行判断,通过递归合并为完整树的判断。
在此题中,编写函数针对当前节点
cur
,获取以cur
为根节点的树的最大路径和,首先分别获取左右子树的最大路径和,然后判断此树的最大路径。(进入叶子节点子树的时候,因为为null,最大路径和就直接返回0,即空结点返回0)。如何选择最大路径,当已有子树最大路径
left
,right
时,其实有三种选择:leftNode-curNode
,当前节点与左子树连接的路径,那么最大路径和为left+curVal
curNode-rightNode
,当前节点与右子树连接的路径,和为right+curVal
curNode
,只有当前节点,和为curVal
为什么有第三种情况呢?因为有可能左右子树都是负数,加他们还不如不加。
其实这也对应着从上往下走,选路径的过程,当走到当前节点
cur
时,有三个方向可以走:- 往左子节点走
- 往右子节点走
- 停止,不往下走
代码如下,有详细注释
1.0
class Solution {
public:
int maxx=-10000;
int work(TreeNode* cur){//以cur节点为根节点的一棵树的路径最大值
if(cur==nullptr)
return 0;
int left=work(cur->left);
int right=work(cur->right);
int curMax=-10000;//以cur节点为根节点的一棵树的路径最大值
curMax=max(curMax,cur->val);//与当前节点比,对应的情况是两个子树为负
curMax=max(curMax,left+cur->val);//当前节点连接左子树的路径,注意只有一条路径,所以不能左右子树+当前节点,不然会出现F形状的路径
curMax=max(curMax,right+cur->val);//连接右
maxx=max(maxx,max(left+right+cur->val,curMax));//而所有树最大路径和maxx,是必须算上当前节点来比较的
return curMax;
}
int maxPathSum(TreeNode* root) {
if(root==nullptr)
return 0;
work(root);
return maxx;
}
};
2.0
如果感觉1.0的代码有太多判断,就可以参考官方中的小技巧,即获得子树最大路径和时,加一个判断,取和与0的较大值,,即可省略掉后面的判断,而且逻辑更好理解。
查看代码
/**
* 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 maxx=-10000;
int work(TreeNode* cur){//以cur节点为根节点的一棵树的路径最大值
if(cur==nullptr)
return 0;
int left=max(work(cur->left),0);
int right=max(work(cur->right),0);
maxx=max(maxx,left+right+cur->val);//更新maxx
return cur->val+max(left,right);
}
int maxPathSum(TreeNode* root) {
if(root==nullptr)
return 0;
work(root);
return maxx;
}
};