## 题目

> - 题号：124
> - 难度：困难
> - https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/

给定一个非空二叉树，返回其最大路径和。

本题中，路径被定义为一条从树中任意节点出发，达到任意节点的序列。该路径<b>至少包含一个节点</b>，且不一定经过根节点。

<b>示例 1</b>:
```c
输入: [1,2,3]

       1
      / \
     2   3

输出: 6
```

<b>示例 2</b>:
```c
输入: [-10,9,20,null,null,15,7]

   -10
   / \
  9  20
    /  \
   15   7

输出: 42
```


---
## 实现


对于任意一个节点, 如果最大和路径包含该节点, 那么只可能是两种情况：
- 其左右子树中所构成的和路径值较大的那个加上该节点的值后向父节点回溯构成最大路径。
- 左右子树都在最大路径中, 加上该节点的值构成了最终的最大路径。

```c
     8
    / \
  -3   7
 /  \
1    4
```
考虑左子树 -3 的路径的时候，我们有左子树 1 和右子树 4 的选择，但我们不能同时选择。

如果同时选了，路径就是 ... -> 1 -> -3 -> 4 就无法通过根节点 8 了。

所以我们只能去求左子树能返回的最大值，右子树能返回的最大值，选一个较大的。

- 状态：通过
- 93 / 93 个通过测试用例
- 执行用时: 152 ms, 在所有 C# 提交中击败了 86.96% 的用户
- 内存消耗: 29.7 MB, 在所有 C# 提交中击败了 37.50% 的用户

```c
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left;
 *     public TreeNode right;
 *     public TreeNode(int x) { val = x; }
 * }
 */
public class Solution
{
    private int _max = int.MinValue;
    public int MaxPathSum(TreeNode root)
    {
        MaxPath(root);
        return _max;
    }

    private int MaxPath(TreeNode current)
    {
        if (current == null)
            return 0;
        // 如果子树路径和为负则应当置0表示最大路径不包含子树
        int left = Math.Max(MaxPath(current.left), 0);
        int right = Math.Max(MaxPath(current.right), 0);
        
        // 判断在该节点包含左右子树的路径和是否大于当前最大路径和
        _max = Math.Max(_max, current.val + left + right);
        return current.val + Math.Max(left, right);
    }
}
```



