我在接受采访时被问到这个问题。考虑二叉树,我们需要打印最长路径的长度,其中每个元素相差1。
EG:
6
/ \
5 7
/ \ / \
2 4 8 9
回答:5
(4,5,6,7,8)
怎么做? 我开发了一个algoirthm来打印从根到叶的增加路径,但我不是要开发一个跟踪两个子树上的路径的路径。
编辑:修改后需要取回原始树。
答案 0 :(得分:2)
正如@qwertyman在评论中所建议的
删除所有无效边,即差异大于1的边
现在我们有一个森林,为每个森林计算直径,因为它在@FilipKočica解决方案中给出
答案是所有森林的最大直径
答案 1 :(得分:1)
对于每个子树,您可以计算从子树根向下延伸的最长路径,向下延伸最长路径,以及从子树中任何位置的同一节点向下增加和减少路径组成的最长内部路径。
如果您已经为所有子节点创建了这些节点,则很容易计算它们,因此您可以将其作为任何后序遍历的一部分。
答案是整棵树内最长的内部路径。
答案 2 :(得分:1)
答案不正确 - 另一位用户正确指出了一个错误。我的解决方案仅在最大长度路径通过根时才起作用。例如,如果最大长度路径完全在左子树中并且没有通过根,则此答案将失败。请随意阅读以熟悉递归解决方案......以及其中的错误。
我假设路径必须具有+1的差异并不重要,如您的示例所示。差异为-1,导致类似4 -> 5 -> 4 -> 3 -> 4 -> 5
的路径也可以。
public int getLongestConsecutivePath(TreeNode root) {
return root == null
? 0
: getLength(root.left, root.value) + getLength(root.right, root.value);
}
private int getLength(TreeNode node, int prevVal) {
return node == null || Math.abs(node.value - prevVal) > 1
? 0
: Math.max(getLength(node.left, node.value), getLength(node.right, node.value)) + 1;
}
<强>解释强>
答案 3 :(得分:1)
让longest_desc[a]
成为从a下降的最长1-by-1下行路径
类似地longest_asc[a]
,从
对于固定的根R,答案为longest_desc[R] + longest_asc[R] - 1
。
一个强制解决方案将从每个节点X执行2次dfs / bfs遍历以计算longest_asc[X] and longest_desc[X]
,然后将它们合并在一起。产生的运行时复杂性为O(n^2)
。
但我们实际上可以使用动态编程做得更好:
longest_asc[X] = max(longest_asc[Y in children[X]] with Y = X + 1)
longest_desc[X] = max(longest_desc[Y in children[X]] with Y = X - 1)
然后我们可以计算单个DFS遍历中的所有值=&gt; O(n)
解决方案。