I started with DFS because that felt natural, tracking nodes in three states: unvisited, currently in the recursion stack, and fully processed.
Start by clarifying the graph properties (directed, possible self-loops, multiple edges) and then present two distinct approaches: DFS with recursion stack and Kahn's algorithm. For each, explain the algorithm, walk through a small example, and analyze time and space complexity. Conclude by comparing trade-offs and mentioning edge cases.
Pro tip: Emphasize that Kahn's algorithm can also produce a topological order if no cycle exists, which is useful in many applications. Also, mention that DFS recursion depth may cause stack overflow for large graphs, so an iterative version or Kahn's algorithm might be preferred in production.
Ask if the graph can have self-loops or multiple edges, and confirm that we need to detect any cycle. Mention that self-loops are cycles and that the graph may be disconnected.
Describe using three states (unvisited, visiting, visited) to track nodes in the current recursion stack. If a node is encountered that is already in the 'visiting' state, a cycle exists. Walk through a small example.
Compute in-degrees, enqueue nodes with in-degree 0, and repeatedly remove nodes and decrement in-degrees of neighbors. If the number of processed nodes is less than n, a cycle exists. Walk through a small example.
Both approaches run in O(n + m) time and use O(n + m) space for the adjacency list and auxiliary data structures. Mention that DFS recursion uses O(n) stack space in the worst case.
Discuss when to prefer each: DFS is simpler to implement recursively but may risk stack overflow; Kahn's algorithm is iterative and can also produce a topological order. Mention that both are optimal for this problem.
AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.