Solution 1
需要额外注意一点,本题允许的路径的重点并没有强制为叶子节点。
回溯过程中,需要维护两个状态:
- 最大路径方案值:即在以当前节点为根节点的子树中,到达当前节点的路径的价值,用于回溯过程中计算经过当前节点并终止于当前节点作为根节点的子树中的节点的路径和(左右加和)
- 最大路径和:即起讫均在当前节点作为根节点的子树中的路径和(左右加和)
前者的计算需要额外考虑一点,如果方案值回溯结果为负,就置为0(重点,此时整个子树的贡献为负,当前节点为重点是最佳方案)。
- 时间复杂度: O ( N ) O(N) O(N),其中 N N N为输入树的节点个数,回溯过程每个节点遍历至多两次
- 空间复杂度: O ( N ) O(N) O(N),其中 N N N为输入树的节点个数,取决于回溯过程中函数占用,最坏情况为一侧树
/**
* 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 ans = INT_MIN;
this->check(root, ans);
return ans;
}
private:
int check(TreeNode* node, int & maxSum) {
if (node == nullptr) {
return 0; // 空节点,最佳路径方案值为0
}
// 左右最佳路径方案值
int maxLeftValue = max(this->check(node->left, maxSum), 0);
int maxRightValue = max(this->check(node->right, maxSum), 0);
// 更新最大路径和
maxSum = max(maxSum, node->val + maxLeftValue + maxRightValue);
// 当前节点的最大路径方案
return node->val + max(maxLeftValue, maxRightValue);
}
};
Solution 2
Solution 1的Python实现
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxPathSum(self, root: Optional[TreeNode]) -> int:
def check(node: Optional[TreeNode]) -> int:
nonlocal ans
if node is None:
return 0
maxLeftValue = max(check(node.left), 0)
maxRightValue = max(check(node.right), 0)
if ans is None:
ans = node.val + maxLeftValue + maxRightValue
else:
ans = max(ans, node.val + maxLeftValue + maxRightValue)
return node.val + max(maxLeftValue, maxRightValue)
ans = None
check(root)
return ans