【问题标题】:Kahn's algorithm vs DFS for course schedule leetcode用于课程安排的卡恩算法 vs DFS leetcode
【发布时间】:2021-09-19 06:13:51
【问题描述】:

课程安排leetcode:https://leetcode.com/problems/course-schedule/

这个问题涉及检测一个循环,如果有循环,那么你就不能完成所有课程。

我听说最推荐使用 DFS 来检测周期,但推荐使用 Kahn 算法来解决课程安排问题,这是一种 BFS 解决方案。

那么.. 是哪一个? DFS 更适合检测周期还是 BFS?

【问题讨论】:

  • 最大的不同是Khan的必须一直持续到最后,如果有的话,DFS可以更早地进入循环。好问题是没有循环时谁更快,这是一个实施质量问题。
  • Khan的算法与BFS无关

标签: algorithm data-structures graph depth-first-search breadth-first-search


【解决方案1】:

在实际工作中,使用 O(N) 堆栈空间总是一个坏主意,因此基于 DFS 的实用解决方案将使用显式堆栈。

显式栈实现有点复杂,因为栈不仅仅是节点栈——你还需要为每个打开的节点将当前位置存储在子列表中——并且遍历逻辑有点复杂复杂。

DFS 解决方案并不糟糕,但如果你想写出一个好的可靠解决方案,那么在最坏的情况下,Khan 的算法最终会变得更简单、更快。它也将使用更少的内存,因为挂起的节点列表只是一个节点列表。 (如果你像堆栈或队列一样使用该列表并不重要。在大多数情况下,像堆栈一样使用它更快/更容易)

因此,如果您要显式检查 DAG 以查看它是否有循环,通常 Khan 的算法是最好的。如果您出于其他原因已经在执行 DFS,并且您希望在此过程中检测循环,则 DFS 技术很有用。

【讨论】:

    【解决方案2】:

    两者的时间复杂度都是 O(V+E),空间复杂度都是 O(V+E)。所以在这些方面没有赢家。

    一个使用队列,另一个使用堆栈。一个使用每个节点的度数,另一个使用每个节点的访问标记。

    一个区别是 DFS 可以通过递归使用隐式堆栈,这可能会使代码更紧凑。但是话又说回来,您会受到可用调用堆栈空间的限制,因此使用递归可能不是大型输入的可行解决方案,而使用显式堆栈最终可能是基于 DFS 的解决方案的选择。

    总而言之,他们的结果是平等的。选择其中一个。

    【讨论】:

      猜你喜欢
      • 2012-10-31
      • 1970-01-01
      • 2017-09-27
      • 1970-01-01
      • 2020-08-08
      • 2015-07-19
      • 1970-01-01
      • 2019-08-07
      • 2021-06-27
      相关资源
      最近更新 更多