它是一般树(非循环图),因此只能有一条这样的路径。我可以使用什么算法?
编辑:
需要找到树中所有顶点对的路径
答案 0 :(得分:1)
我想在这里扩展@ templatetypedef的答案 1 。
请注意,在您的问题中,您需要在树中每对节点至少执行一次写入操作。这些中有n*(n-1)/2
个。
因此,就大O符号而言,您找不到比O(n^2)
更好的算法。
现在,使用DFS或BFS查找每个节点的路径。它将在O(n+m)
(n
个顶点,m
边缘运行。但由于它是一棵树,我们知道m=n-1
,给我们O(n)
BFS / DFS。请注意,在某个节点v
的单个BFS / DFS中,每个节点d(v,u)
都会得到u
。
如果你按每个节点重复它,它会得到O(n^2)
- 这对于大O表示法来说是最佳的。我同意你可以通过一些优化获得更好的常量,但这就是它。
(1)作为评论开始,但它太长了,我觉得值得回答。
答案 1 :(得分:0)
一个简单的选项是从其中一个节点开始深度优先搜索,直到到达另一个节点。然后,您可以查看从第一个节点到第二个节点的路径,该路径必须是这些节点之间的唯一路径,然后计算该路径中的边数。这是在线性时间内运行的,因为树上的DFS只需要线性时间。
希望这有帮助!
答案 2 :(得分:0)
您需要找到Lowest Common Ancestor(LCA)。您可以在此处学习不同的方法:http://leetcode.com/2011/07/lowest-common-ancestor-of-a-binary-tree-part-i.html
我已经使用过这种解决方案,因为我不喜欢递归,因为你需要以有效的方式找到所有对,因此应该更好地解决你的问题。
1-)找到A - >之间的路径。 B: - 从节点A开始迭代,每个父节点用A标志标记每个父节点,直到父根基金为止。 - 从节点B开始直到找到A Flag为止。您找到了LCA节点。 - 结果路径是从A到LCA节点的列表,以及从B到LCA节点的反向列表。
2-)改进发现A - > B: - 同时迭代两个节点,用A标志标记,B标记每个祖先节点。直到A迭代找到B标志或B迭代找到A标志。然后第一个找到另一个节点标志找到了LCA节点。
3-)查找所有对路径: 您可以简单地为每对使用上面的解决方案。 或者尝试考虑首先迭代所有树创建标志列表,然后第二次传递以识别每对的所有LCA节点,当树节点数量变得太大时这将是不方便的。