DFS (Depth-First Search) and BFS (Breadth-First Search) are fundamental graph traversal algorithms used to explore nodes and edges in graphs or trees.
- DFS explores as deep as possible before backtracking.
- BFS explores level by level using a queue.
Both algorithms are used to:
- Traverse graphs and grids
- Find connected components
- Detect cycles
- Check reachability
- Find shortest paths in unweighted graphs (BFS)
Many problems that don’t look like graphs actually are:
- Grid problems → graph of cells
- Islands / regions → connected components
- Word transformations → graph of words
- Course prerequisites → directed graph
If a problem asks you to visit all reachable neighbors, think DFS/BFS.
| Use Case | BFS | DFS |
|---|---|---|
| Traverse all nodes | ✅ | ✅ |
| Shortest path (unweighted) | ✅ | ❌ |
| Connected components | ✅ | ✅ |
| Cycle detection | ❌ | ✅ |
| Topological sort | ❌ | ✅ |
| Flood fill / islands | ✅ | ✅ |
| Avoid recursion stack overflow | ✅ | ❌ |
- All nodes are reachable from a single start node
- One BFS/DFS call is enough
- Graph has multiple components
- Requires an outer loop
- Each BFS/DFS call processes one component
💡 Rule of thumb:
If you need an outer loop to start BFS/DFS multiple times → the graph is disconnected.
void bfsConnected(List<List<Integer>> graph, int start) {
boolean[] visited = new boolean[graph.size()];
Queue<Integer> queue = new LinkedList<>();
visited[start] = true;
queue.offer(start);
while (!queue.isEmpty()) {
int node = queue.poll();
System.out.print(node + " ");
for (int neighbor : graph.get(node)) {
if (!visited[neighbor]) {
visited[neighbor] = true;
queue.offer(neighbor);
}
}
}
}- Graph is guaranteed to be connected
- You are given a starting node (e.g. Clone Graph)
void bfsDisconnected(List<List<Integer>> graph) {
boolean[] visited = new boolean[graph.size()];
for (int i = 0; i < graph.size(); i++) {
if (!visited[i]) {
bfs(graph, i, visited);
}
}
}- Counting components (e.g. Number of Islands)
- Graph may be disconnected
void dfsConnected(List<List<Integer>> graph, int start) {
boolean[] visited = new boolean[graph.size()];
dfs(start, graph, visited);
}
void dfs(int node, List<List<Integer>> graph, boolean[] visited) {
visited[node] = true;
System.out.print(node + " ");
for (int neighbor : graph.get(node)) {
if (!visited[neighbor]) {
dfs(neighbor, graph, visited);
}
}
}- Graph is connected
- Depth-first exploration is needed
void dfsDisconnected(List<List<Integer>> graph) {
boolean[] visited = new boolean[graph.size()];
for (int i = 0; i < graph.size(); i++) {
if (!visited[i]) {
dfs(i, graph, visited);
}
}
}- Counting connected components
- Grid problems (islands, regions)
- Cycle detection in graphs
| # | Name | Java | Python | Go | Link | Company |
|---|---|---|---|---|---|---|
| 1 | Number of Islands | ✅ | ✅ | ❌ | LeetCode #200 | |
| 2 | Clone Graph | ✅ | ✅ | ❌ | LeetCode #133 | |
| 3 | Word Ladder | ✅ | ✅ | ❌ | LeetCode #127 | |
| 4 | Course Schedule | ✅ | ❌ | ❌ | LeetCode #207 | |
| 5 | Pacific Atlantic Water Flow | ✅ | ❌ | ❌ | LeetCode #417 | |
| 6 | Word Search | ✅ | ❌ | ❌ | LeetCode #79 |