DFS Depth First Search on Graph in DSA Python - Time & Space Complexity
We want to understand how the time taken by Depth First Search (DFS) changes as the graph size grows.
Specifically, how the number of nodes and edges affects the work done.
Analyze the time complexity of the following DFS code on a graph.
def dfs(graph, node, visited):
visited.add(node)
for neighbor in graph[node]:
if neighbor not in visited:
dfs(graph, neighbor, visited)
This code visits all nodes reachable from the starting node using recursion.
Look for loops and recursive calls that repeat work.
- Primary operation: Visiting each node and exploring its neighbors.
- How many times: Each node is visited once, and each edge is checked once.
As the graph grows, DFS visits every node and edge once.
| Input Size (n nodes, m edges) | Approx. Operations |
|---|---|
| 10 nodes, 15 edges | About 25 operations (10 nodes + 15 edges) |
| 100 nodes, 200 edges | About 300 operations (100 + 200) |
| 1000 nodes, 5000 edges | About 6000 operations (1000 + 5000) |
Pattern observation: Operations grow roughly with the sum of nodes and edges.
Time Complexity: O(n + m)
This means the time grows linearly with the number of nodes plus the number of edges in the graph.
[X] Wrong: "DFS always takes O(n²) time because it uses recursion inside a loop."
[OK] Correct: DFS visits each node and edge only once, so it does not repeat work unnecessarily. The recursion does not multiply work but helps explore neighbors efficiently.
Understanding DFS time complexity helps you explain how graph traversal scales and why it is efficient for many problems.
"What if the graph is represented as an adjacency matrix instead of adjacency lists? How would the time complexity change?"
Practice
Solution
Step 1: Understand DFS traversal
DFS explores a graph by going deep into one branch before backtracking to explore others.Step 2: Compare with other traversal methods
BFS explores neighbors level by level, but DFS goes deep first.Final Answer:
It explores as far as possible along each branch before backtracking. -> Option AQuick Check:
DFS = deep exploration first [OK]
- Confusing DFS with BFS
- Thinking DFS visits nodes randomly
- Assuming DFS visits nodes by value
graph from node start?Solution
Step 1: Identify required parameters for DFS
DFS needs the graph and the starting node to begin traversal.Step 2: Check function signature correctness
def dfs(graph, start): correctly defines a function with parameters (graph, start).Final Answer:
def dfs(graph, start): -> Option BQuick Check:
DFS needs graph and start node [OK]
- Swapping parameter order incorrectly
- Missing one of the parameters
- Using only one parameter when two are needed
graph = {0: [1, 2], 1: [2], 2: [0, 3], 3: [3]}
visited = set()
def dfs(node):
if node not in visited:
print(node, end=' ')
visited.add(node)
for neighbor in graph[node]:
dfs(neighbor)
dfs(0)Solution
Step 1: Start DFS from node 0
Visit 0, mark visited. Neighbors: 1, 2.Step 2: Visit neighbor 1
Visit 1, mark visited. Neighbor: 2.Step 3: Visit neighbor 2
Visit 2, mark visited. Neighbors: 0 (visited), 3.Step 4: Visit neighbor 3
Visit 3, mark visited. Neighbor: 3 (already visited).Final Answer:
0 1 2 3 -> Option DQuick Check:
DFS order = 0 1 2 3 [OK]
- Visiting neighbors in wrong order
- Revisiting already visited nodes
- Confusing BFS order with DFS
graph = {0: [1], 1: [2], 2: []}
visited = set()
def dfs(node):
if node in visited:
return
print(node)
for neighbor in graph[node]:
dfs(neighbor)
dfs(0)Solution
Step 1: Identify missing visited marking
The code never adds nodes to visited, so it revisits nodes infinitely.Step 2: Fix by adding visited marking
Adding 'visited.add(node)' after printing marks node as visited to avoid revisits.Final Answer:
Add 'visited.add(node)' after printing node to mark it visited. -> Option AQuick Check:
Mark visited after visiting node [OK]
- Forgetting to mark nodes visited
- Incorrect if condition logic
- Removing nodes from visited incorrectly
graph = {0: [1, 2], 1: [2], 2: [3], 3: [1]}
Write the DFS traversal order starting from node 0 that detects cycles by tracking recursion stack. What is the order of nodes visited before detecting a cycle?Solution
Step 1: Start DFS from node 0 and track recursion stack
Visit 0, then 1, then 2, then 3. At 3, neighbor 1 is in recursion stack, cycle detected.Step 2: List nodes visited before cycle detection
Nodes visited in order: 0, 1, 2, 3 before cycle found.Final Answer:
0 1 2 3 -> Option CQuick Check:
DFS with cycle detection visits 0 1 2 3 [OK]
- Ignoring recursion stack for cycle detection
- Stopping traversal too early
- Visiting nodes in wrong order
Ready to prove it?
Pass the test and this pattern moves unknown
