本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目链接:124. 二叉树中的最大路径和
题目描述【hard】
解题思路
1.初见
本题作为二叉树的遍历问题,第一想到的解题方式就是遍历,树、图的遍历方式主要包含DFS、BFS,使用遍历方式解题的思路:二叉树的求解‘最长的子路径’,与常见的「最长子路径:根节点到叶子结点最长子路径」不同,此处路径可以将二叉树视为一个无向图,求解任意两个节点直接路径和最大值,将其拆分为包含根节点的最长子路径以及不包含根节点左子树、右子树的最长子路径,进行递归求解。
相比常规二叉树最长子序列存在以下不同:
- 子序列可以包括根节点;
- 子序列不再是从根节点到叶子结点,任意节点之间可达即为子序列;
- 单个节点也是子序列;
代码-1.初见
private static int CUR_MAX = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
if (root == null) {
return Integer.MIN_VALUE;
}
// 包含根节点的最长子路径
int includeRootMaxPath =
getMaxTreePath(root.left) + getMaxTreePath(root.right) + root.val;
// 1.仅包含根节点 2.包含根节点子路径 3.左子树、右子树最长子路径
return Math.max(Math.max(root.val, includeRootMaxPath), Math.max(maxPathSum(root.left), maxPathSum(root.right)));
}
private int getMaxTreePath(TreeNode node) {
CUR_MAX = Integer.MIN_VALUE;
getMaxTreePath(node, 0);
return Math.max(0, CUR_MAX);
}
private void getMaxTreePath(TreeNode node, int path) {
// 记录任意子路径中最大值
if (path > CUR_MAX) {
CUR_MAX = path;
}
if (node == null) {
return;
}
// DFS求解二叉树遍历问题
getMaxTreePath(node.left, path + node.val);
getMaxTreePath(node.right, path + node.val);
return;
}
- 时间复杂度:O(N)
- 空间复杂度:O(N)
2.归途
本题的题意比较清晰,最终是二叉树子路径问题的变种,针对二叉树的子路径问题,能想到的就是进行遍历DFS、BFS,通过遍历二叉树,记录遍历过程中出现的各种子路径,更新最长的子路径,本题只需要记录最大子路径和即可,当需要记录最长子路径时,代码无需过多修改,增加记录最长子路径的列表即可,维护全局最长子路径。
BFS遍历的方式采用队列Queue保存节点,入队当前节点,出队,将其可达节点入队,依次下去,设置好终止条件,遍历整个二叉树。
init queue;
queue.add(root);
// BFS广度优先遍历二叉树
while (!queue.isEmpty())
x = queue.poll();
// 终止条件
if X is visted or end
continue
else
x.left x.right add queue
update maxLen