# 题目要求
路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。
路径和 是路径中各节点值的总和。
给你一个二叉树的根节点 root ,返回其 最大路径和 。
# 思路
路径每到一个节点,只有3中选择:①停在当前节点。②走到左子节点。 ③走到右子节点。
走到子节点,又有三种选择,递归就是用来处理规模不一样的相同问题。
注意:不能走进一个分支又掉头。
定义递归函数
- dfs函数:返回当前子树能向父节点提供的最大路径和
maxSum
,①子树根节点,收益为root.val
②左子树收益root.val+dfs(root.left)
③右子树收益root.val + dfs(root.right)
- 当遍历到
root
节点时,返回0; - 如果遇到负数,像
null
一样放回0;
子树内部路径要包含根节点
- 每递归一个子树,都求一下当前子树内部的最大路径和,再从中比较出最大的。
- 子树内部最大路径和
innerMaxSum
= 左子树提供的最大路径和dfs(root.left)
+ 根节点root.val
+ 右子树提供的最大路径和dfs(root.right)
var maxPathMax = function(root){
// 最大路径和,Number.MIN_SAFE_INTEGER最小最安全的integer型数字
let maxSum = Number.MIN_SAFE_INTEGER;
// dfs 函数,递归求子最大路径和
const dfs = (root) => {
// 筛选root中的空节点
if(root == null){
return 0;
}
// 左子树最大路径和
const left = dfs(root.left);
// 左子树最大路径和
const right = dfs(root.right);
// 子树内部最大路径和 = 做子树 + 根节点 + 右子树
const innerMaxSum = left + root.val + right;
// 更新maxSum值
maxSum = Math.max(maxSum, innerMaxSum);
// 子树向外提供最大路径和
const outputMaxSum = root.val + Math.max(left, right);
// 返回时检查有没有负数
return outputMaxSum < 0 ? 0 : outputMaxSum;
};
dfs(root); // 入口
return maxSum;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
← 二分查找高效判定子序列 二叉树的中序遍历 →