Bird
Raised Fist0
DSA C#programming~5 mins

Cycle Detection in Directed Graph in DSA C# - Time & Space Complexity

Choose your learning style10 modes available
Time Complexity: Cycle Detection in Directed Graph
O(n + e)
Understanding Time Complexity

We want to understand how long it takes to find a cycle in a directed graph.

Specifically, how the time grows as the graph gets bigger.

Scenario Under Consideration

Analyze the time complexity of the following code snippet.


// Detect cycle using DFS in directed graph
bool HasCycle(int node, List<int>[] graph, bool[] visited, bool[] recStack) {
    if (!visited[node]) {
        visited[node] = true;
        recStack[node] = true;
        foreach (int neighbor in graph[node]) {
            if (!visited[neighbor] && HasCycle(neighbor, graph, visited, recStack))
                return true;
            else if (recStack[neighbor])
                return true;
        }
    }
    recStack[node] = false;
    return false;
}
    

This code checks if there is a cycle starting from a given node using depth-first search.

Identify Repeating Operations

Identify the loops, recursion, array traversals that repeat.

  • Primary operation: Recursive depth-first search visiting each node and its neighbors.
  • How many times: Each node is visited once, and each edge is checked once during recursion.
How Execution Grows With Input

As the number of nodes and edges grows, the work grows roughly in proportion to their total.

Input Size (n nodes, e edges)Approx. Operations
10 nodes, 15 edgesAbout 25 checks (nodes + edges)
100 nodes, 200 edgesAbout 300 checks
1000 nodes, 5000 edgesAbout 6000 checks

Pattern observation: The operations grow roughly linearly with the sum of nodes and edges.

Final Time Complexity

Time Complexity: O(n + e)

This means the time grows linearly with the number of nodes plus edges in the graph.

Common Mistake

[X] Wrong: "The algorithm checks every possible path, so it must be exponential time."

[OK] Correct: The algorithm marks nodes visited and does not revisit them, so it only processes each node and edge once, avoiding repeated work.

Interview Connect

Understanding this time complexity helps you explain how your cycle detection scales and why it is efficient for large graphs.

Self-Check

"What if the graph was represented as an adjacency matrix instead of adjacency lists? How would the time complexity change?"

Practice

(1/5)
1. What does cycle detection in a directed graph help us find?
easy
A. Whether there is a path that starts and ends at the same vertex following edge directions
B. The shortest path between two vertices
C. The total number of vertices in the graph
D. The maximum degree of any vertex

Solution

  1. Step 1: Understand cycle in directed graph

    A cycle means a path that starts and ends at the same vertex following the direction of edges.
  2. Step 2: Identify what cycle detection finds

    Cycle detection checks if such a path exists in the graph.
  3. Final Answer:

    Whether there is a path that starts and ends at the same vertex following edge directions -> Option A
  4. Quick Check:

    Cycle detection = finding directed cycles [OK]
Hint: Cycle means path loops back following edge directions [OK]
Common Mistakes:
  • Confusing cycle with shortest path
  • Ignoring edge directions
  • Thinking cycle means any repeated vertex
2. Which C# data structure is commonly used to keep track of nodes currently in the recursion stack during DFS for cycle detection?
easy
A. Queue
B. Stack or boolean array to mark recursion stack
C. Dictionary
D. LinkedList

Solution

  1. Step 1: Recall DFS cycle detection method

    During DFS, we track nodes in the current recursion path to detect back edges.
  2. Step 2: Identify data structure used

    This is done using a stack or a boolean array marking nodes in the recursion stack.
  3. Final Answer:

    Stack or boolean array to mark recursion stack -> Option B
  4. Quick Check:

    Recursion stack tracking = Stack/boolean array [OK]
Hint: Use stack or boolean array to track recursion path [OK]
Common Mistakes:
  • Using queue which is FIFO, not suitable for recursion stack
  • Confusing dictionary with recursion tracking
  • Not marking nodes currently in recursion
3. What will be the output of the following C# code snippet detecting cycle in a directed graph?
var graph = new Dictionary<int, List<int>> {
  {1, new List<int>{2}},
  {2, new List<int>{3}},
  {3, new List<int>{1}}
};
bool HasCycle(int node, HashSet<int> visited, HashSet<int> recStack) {
  if (!visited.Contains(node)) {
    visited.Add(node);
    recStack.Add(node);
    foreach (var neighbor in graph[node]) {
      if (!visited.Contains(neighbor) && HasCycle(neighbor, visited, recStack))
        return true;
      else if (recStack.Contains(neighbor))
        return true;
    }
  }
  recStack.Remove(node);
  return false;
}

var visited = new HashSet<int>();
var recStack = new HashSet<int>();
Console.WriteLine(HasCycle(1, visited, recStack));
medium
A. False
B. Compilation error
C. Runtime exception
D. True

Solution

  1. Step 1: Analyze graph edges

    The graph has edges 1->2, 2->3, and 3->1 forming a cycle.
  2. Step 2: Trace DFS cycle detection

    Starting at node 1, recursion visits 2, then 3, then back to 1 which is in recursion stack, so cycle detected.
  3. Final Answer:

    True -> Option D
  4. Quick Check:

    Cycle exists in graph = True [OK]
Hint: Cycle if recursion stack revisits a node [OK]
Common Mistakes:
  • Ignoring recursion stack check
  • Assuming no cycle because graph looks simple
  • Confusing visited set with recursion stack
4. Identify the bug in this C# DFS cycle detection code snippet:
bool HasCycle(int node, HashSet<int> visited, HashSet<int> recStack) {
  visited.Add(node);
  foreach (var neighbor in graph[node]) {
    if (!visited.Contains(neighbor) && HasCycle(neighbor, visited, recStack))
      return true;
    else if (recStack.Contains(neighbor))
      return true;
  }
  recStack.Remove(node);
  return false;
}
medium
A. Missing removing node from visited after recursion
B. Incorrect use of HashSet instead of List
C. Missing adding node to recStack before recursion
D. No bug, code is correct

Solution

  1. Step 1: Check recursion stack usage

    Node must be added to recStack before exploring neighbors to detect back edges.
  2. Step 2: Identify missing step

    Code adds node to visited but never adds to recStack before recursion, so cycle detection fails.
  3. Final Answer:

    Missing adding node to recStack before recursion -> Option C
  4. Quick Check:

    recStack update missing = bug [OK]
Hint: Always add node to recursion stack before DFS call [OK]
Common Mistakes:
  • Forgetting to add node to recursion stack
  • Removing node from visited incorrectly
  • Confusing visited and recursion stack roles
5. Given a directed graph represented as adjacency list:
var graph = new Dictionary<int, List<int>> {
  {1, new List<int>{2, 3}},
  {2, new List<int>{4}},
  {3, new List<int>{4}},
  {4, new List<int>{5}},
  {5, new List<int>{3}}
};
Which nodes form a cycle in this graph?
hard
A. Nodes 3, 4, 5
B. Nodes 1, 2, 4
C. Nodes 2, 3, 5
D. No cycle exists

Solution

  1. Step 1: Trace edges to find cycle

    Edges: 3->4, 4->5, 5->3 form a cycle among nodes 3, 4, 5.
  2. Step 2: Confirm cycle presence

    Starting at 3, path 3->4->5->3 loops back, confirming cycle.
  3. Final Answer:

    Nodes 3, 4, 5 -> Option A
  4. Quick Check:

    Cycle nodes = 3,4,5 [OK]
Hint: Follow edges to see if path loops back to start [OK]
Common Mistakes:
  • Ignoring edge 5->3 that closes cycle
  • Assuming no cycle because 1 and 2 are acyclic
  • Confusing cycle nodes with all connected nodes
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard