给你一个二叉树的根节点 root ,返回其最大路径和
https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/
路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点
路径和 是路径中各节点值的总和。
示例1:
1 / \ 2 3
输入:root = [1,2,3]
输出:6
解释:最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6
示例2:
-10 / \ 9 20 / \ 15 7
输入:root = [-10,9,20,null,null,15,7]
输出:42
解释:最优路径是 15 -> 20 -> 7 ,路径和为 15 + 20 + 7 = 42
提示:
树中节点数目范围是 [1, 3 * 104]
-1000 <= Node.val <= 1000
Java解法
思路:
- 说实话,题目比较难理解,但多看几遍还是理解出来了
- 实际上就是从二叉树的某个点出发,使得经过的数字之后为最大,这种试探推出结果的方式可以考虑通过回溯来控制输出结果
- emmm,死在这上面了,MD这个不是完全二叉树,自己写的是二叉树工具类,坑死自己,不过基本跑通了84/92个用例,菜鸡
- 参考使用递归处理
public int maxGain(TreeNode node) {
if (node == null) {
return 0;
}
// 递归计算左右子节点的最大贡献值
// 只有在最大贡献值大于 0 时,才会选取对应子节点
int leftGain = Math.max(maxGain(node.left), 0);
int rightGain = Math.max(maxGain(node.right), 0);
// 节点的最大路径和取决于该节点的值与该节点的左右子节点的最大贡献值
int priceNewpath = node.val + leftGain + rightGain;
// 更新答案
maxSum = Math.max(maxSum, priceNewpath);//这个为实际答案,在递归当中更新最大值返回
// 返回节点的最大贡献值
return node.val + Math.max(leftGain, rightGain);
}
//错误示范
public static void back(Integer[] roots, int length, int index, List<Integer> path, int pathSum) {
boolean canGo = false;
//当前节点的走法
int parent = (index - 1) / 2;
if (parent < length && roots[parent] != null && !path.contains(parent)) {
canGo = true;
path.add(parent);
if (roots[parent] < 0) {
//负数经过之前先记录一次
results.add(pathSum);
paths.add(new ArrayList<>(path));
}
back(roots, length, parent, path, pathSum + roots[parent]);
path.remove(path.size() - 1);
}
int left = 2 * (index + 1) - 1;
if (left < length && roots[left] != null && !path.contains(left)) {
canGo = true;
path.add(left);
if (roots[left] < 0) {
//负数经过之前先记录一次
results.add(pathSum);
paths.add(new ArrayList<>(path));
}
back(roots, length, left, path, pathSum + roots[left]);
path.remove(path.size() - 1);
}
int right = left + 1;
if (right < length && roots[right] != null && !path.contains(right)) {
canGo = true;
path.add(right);
if (roots[right] < 0) {
//负数经过之前先记录一次
results.add(pathSum);
paths.add(new ArrayList<>(path));
}
back(roots, length, right, path, pathSum + roots[right]);
path.remove(path.size() - 1);
}
if (!canGo) {
results.add(pathSum);
paths.add(new ArrayList<>(path));
}
}
![](https://img.haomeiwen.com/i3026588/1f17231532678e2b.png)
官方解
-
递归
要不要遍历某个节点就看这个节点是否大于0,大于的话则经过它
不得不说牛逼
-
时间复杂度:O(N)
-
空间复杂度:O(N)
-
网友评论