Bird
Raised Fist0
DSA Pythonprogramming~5 mins

Cycle Detection in Undirected Graph in DSA Python - Time & Space Complexity

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

We want to understand how the time needed to detect a cycle in an undirected graph changes as the graph grows.

Specifically, how does the number of nodes and edges affect the work done?

Scenario Under Consideration

Analyze the time complexity of the following code snippet.


def dfs(node, parent, graph, visited):
    visited[node] = True
    for neighbor in graph[node]:
        if not visited[neighbor]:
            if dfs(neighbor, node, graph, visited):
                return True
        elif neighbor != parent:
            return True
    return False

# graph is adjacency list, visited is list of booleans
for vertex in range(len(graph)):
    if not visited[vertex]:
        if dfs(vertex, -1, graph, visited):
            print("Cycle detected")
            break
    

This code uses depth-first search to check if any cycle exists in an undirected graph.

Identify Repeating Operations

Identify the loops, recursion, array traversals that repeat.

  • Primary operation: Visiting each node and exploring all its neighbors using DFS recursion.
  • How many times: Each node is visited once, and each edge is checked twice (once from each end).
How Execution Grows With Input

As the number of nodes (n) and edges (e) grow, the DFS explores all nodes and edges once.

Input Size (n, e)Approx. Operations
10 nodes, 15 edgesAbout 10 + 15*2 = 40 operations
100 nodes, 200 edgesAbout 100 + 200*2 = 500 operations
1000 nodes, 3000 edgesAbout 1000 + 3000*2 = 7000 operations

Pattern observation: The work grows roughly in proportion to the sum of nodes and edges.

Final Time Complexity

Time Complexity: O(n + e)

This means the time to detect a cycle grows linearly with the number of nodes plus edges in the graph.

Common Mistake

[X] Wrong: "Cycle detection only depends on the number of nodes, so it is O(n)."

[OK] Correct: The edges connect nodes and must be checked too; ignoring edges misses part of the work and underestimates time.

Interview Connect

Understanding this time complexity helps you explain how graph traversal scales and why DFS is efficient for cycle detection.

Self-Check

"What if we used a union-find data structure instead of DFS? How would the time complexity change?"

Practice

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

Solution

  1. Step 1: Understand cycle meaning in undirected graph

    A cycle is a path that starts and ends at the same vertex without repeating edges or vertices (except start/end).
  2. Step 2: Identify what cycle detection checks

    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 without repeating edges -> Option B
  4. Quick Check:

    Cycle detection = find loops [OK]
Hint: Cycle means a closed loop path in graph [OK]
Common Mistakes:
  • Confusing cycle with shortest path
  • Thinking cycle counts vertices only
  • Mixing cycle with vertex degree
2. Which Python data structure is commonly used to keep track of visited nodes during cycle detection in an undirected graph?
easy
A. Set
B. List
C. Dictionary
D. Tuple

Solution

  1. Step 1: Identify purpose of visited tracking

    We need to quickly check if a node was visited before to avoid revisiting and detect cycles.
  2. Step 2: Choose data structure with fast membership check

    Set provides O(1) average time for membership checks, making it ideal for visited nodes.
  3. Final Answer:

    Set -> Option A
  4. Quick Check:

    Visited nodes stored in set [OK]
Hint: Use set for fast visited checks [OK]
Common Mistakes:
  • Using list causes slow membership checks
  • Using tuple which is immutable and not suitable
  • Using dictionary unnecessarily when set suffices
3. What will be the output of the following code snippet detecting cycle in an undirected graph?
graph = {0: [1, 2], 1: [0, 2], 2: [0, 1]}
visited = set()
def dfs(node, parent):
    visited.add(node)
    for neighbor in graph[node]:
        if neighbor not in visited:
            if dfs(neighbor, node):
                return True
        elif neighbor != parent:
            return True
    return False

print(dfs(0, -1))
medium
A. True
B. False
C. None
D. Error

Solution

  1. Step 1: Analyze graph structure

    The graph has 3 nodes connected in a triangle: 0-1, 1-2, 2-0, which forms a cycle.
  2. Step 2: Trace DFS cycle detection

    Starting at node 0, DFS visits 1, then 2. When 2 checks neighbors, it finds 0 visited and not parent, so returns True.
  3. Final Answer:

    True -> Option A
  4. Quick Check:

    Triangle graph has cycle = True [OK]
Hint: Triangle graph always has cycle [OK]
Common Mistakes:
  • Ignoring parent check causes false positives
  • Assuming no cycle in small graphs
  • Confusing return values in DFS
4. Find the bug in this cycle detection code for an undirected graph:
def dfs(node, parent, graph, visited):
    visited.add(node)
    for neighbor in graph[node]:
        if neighbor not in visited:
            dfs(neighbor, node, graph, visited)
        elif neighbor != parent:
            return True
    return False
medium
A. Graph should be directed
B. Visited set is not initialized
C. Parent parameter is not used
D. Missing return statement in recursive dfs call

Solution

  1. Step 1: Check recursive call return usage

    The recursive call dfs(neighbor, node, graph, visited) is made but its return value is ignored.
  2. Step 2: Understand impact on cycle detection

    If a cycle is found deeper in recursion, it won't propagate True back up, so function may miss cycles.
  3. Final Answer:

    Missing return statement in recursive dfs call -> Option D
  4. Quick Check:

    Return recursive call result to detect cycles [OK]
Hint: Always return recursive DFS results [OK]
Common Mistakes:
  • Ignoring return value of recursive calls
  • Not passing visited set properly
  • Confusing parent usage
5. Given an undirected graph represented as adjacency list:
graph = {
  0: [1],
  1: [0, 2],
  2: [1, 3],
  3: [2, 4, 5],
  4: [3, 5],
  5: [3, 4]
}
Which nodes form a cycle in this graph?
hard
A. No cycles in this graph
B. Nodes 0, 1, 2 form a cycle
C. Nodes 3, 4, 5 form a cycle
D. All nodes form a cycle

Solution

  1. Step 1: Analyze adjacency list for cycles

    Nodes 3, 4, and 5 connect in a triangle: 3-4, 4-5, 5-3, forming a cycle.
  2. Step 2: Check other nodes for cycles

    Nodes 0, 1, 2 form a simple chain without loops, so no cycle there.
  3. Final Answer:

    Nodes 3, 4, 5 form a cycle -> Option C
  4. Quick Check:

    Triangle subgraph = cycle [OK]
Hint: Look for triangle connections to find cycles [OK]
Common Mistakes:
  • Assuming chain is a cycle
  • Ignoring cycle in subgraph
  • Thinking all nodes must form cycle
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