Commit 7c05b2d2 authored by Yuhang Peng's avatar Yuhang Peng
Browse files

0124 Solved

parent 6db598b8
This image diff could not be displayed because it is too large. You can view the blob instead.
# LeetCode 第 124 号问题:二叉树中的最大路径和
> 本文首发于公众号「图解面试算法」,是 [图解 LeetCode](<https://github.com/MisterBooo/LeetCodeAnimation>) 系列文章之一。
>
> 同步博客:https://www.algomooc.com
题目来源于 LeetCode 上第 124 号问题:二叉树中的最大路径和。题目难度为 Hard,目前通过率为 39.9% 。
<br>
### 题目描述
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
**示例 1:**
```
输入: [1,2,3]
1
/ \
2 3
输出: 6
```
**示例 2:**
```
输入: [-10,9,20,null,null,15,7]
-10
/ \
9 20
/ \
15 7
输出: 42
```
<br>
### 题目解析
二叉树问题,题目要求出一个二叉树的最大路径和,路径和就是把一条路径上面节点的值加起来,这一题的难点在于路径的方向不固定,只要是任意两点间的通路都算是有效路径,如果不提前列出合理的规划,这道题将无从下手。一般来说,解决树的问题都需要用到递归,**树上的搜索,本质上也是深度优先搜索**,但是这里会有两种考虑方式,一个是**自底向上的分治**,也就是进入递归,一开始不做任何节点上面的计算或者是处理,直接进入到下一层递归,直到到了最底层,然后再开始计算并返回答案,然后上层树节点的递归函数就会收到下层返回的结果,这样做的好处是,一个节点可以获知其子树的局部答案;另外一个是**自顶向下的遍历搜索**,这个和之前的思路完全相反,也就是先处理当前节点的内容,处理完后去到下一层节点,这种方法一般没有返回值,但是一般会有一个全局或者是引用变量,用来记录遍历过程中的内容。
我们再回过头来看这道题,在递归遍历的过程中,对于当前节点,其在路径中可以是路径尾,路径头(假设路径是从上到下的,其实在这道题中,没有头尾的概念),也可以是路径中的一个节点。那怎么判断呢?这时我们得需要当前节点左右子树的信息,所以我们可以考虑使用之前提到的 **自底向上** 的分治,有了当前节点,左右子树到当前节点的最大路径,我们可以看看这里会有几种情况,我用 **root** 表示当前节点,**left** 表示左子树到 root 的最大和的路径,**right** 表示右子树到 root 的最大和的路径:
* root 和左右路径形成路径(left - root - right)
* root 和左路径形成路径(left - root)
* root 和右路径形成路径(root - right)
* root 自成路径(root)
你可以看到这四种情况都会把当前节点考虑在内,我们可以更新这里的最大值。但是需要注意的是,我们返回的时候,第一种情况是不能返回的,因为对于上一层节点来说,其无法形成有效的路径,因此我们只需要将 2,3,4 中的最大值返回即可,当然,更新全局答案的时候,这 4 种情况都需要考虑在内的。
<br>
### 代码实现
```java
private int maximum = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
if (root == null) {
return 0;
}
helper(root);
return maximum;
}
private int helper(TreeNode root) {
if (root == null) {
return 0;
}
// 如果左右子树返回的最大路径值小于 0
// 直接将值设为 0,也就是不考虑对应的路径
int leftMax = Math.max(0, helper(root.left));
int rightMax = Math.max(0, helper(root.right));
maximum = Math.max(root.val + leftMax + rightMax, maximum);
return Math.max(leftMax + root.val, rightMax + root.val);
}
```
<br>
### 动画描述
![](../Animation/124.gif)
![](../../Pictures/qrcode.jpg)
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment