Depth First Search
Problem Statement
You are given a set of edges
, n
, and src
, where edges
represents the connection between two nodes, n
represents the number of nodes, and src
represents the source node. Traverse the entire graph in a depth-first fashion.
Example
Input:
edges = [[0, 1], [0, 2], [1, 2], [1, 3], [1, 4], [2, 5], [3, 4], [3, 5]]
n = 6
src = 2
Output:
2 0 1 3 4 5
Video Solution
Java Code
import java.util.ArrayList;
import java.util.List;
class DepthFirstSearch {
public List<List<Integer>> buildGraph(int[][] edges, int n) {
List<List<Integer>> graph = new ArrayList<>();
for(int i = 0; i < n; i++) {
graph.add(new ArrayList<>());
}
for(int[] edge : edges) {
graph.get(edge[0]).add(edge[1]);
graph.get(edge[1]).add(edge[0]);
}
return graph;
}
private void solve(int node, List<Integer> dfsAnswer, List<List<Integer>> graph, boolean[] visited) {
dfsAnswer.add(node);
visited[node] = true;
for(int nbr : graph.get(node)) {
if(!visited[nbr]) {
solve(nbr, dfsAnswer, graph, visited);
}
}
}
private List<Integer> depthFirstSearch(int[][] edges, int n, int src) {
List<List<Integer>> graph = buildGraph(edges, n);
List<Integer> dfsAnswer = new ArrayList<>();
boolean[] visited = new boolean[n];
solve(src, dfsAnswer, graph, visited);
return dfsAnswer;
}
public static void main(String[] args) {
int[][] edges = new int[][]{{0, 1}, {0, 2}, {1, 2}, {1, 3}, {1, 4}, {2, 5}, {3, 4}, {3, 5}};
int n = 6;
int src = 2;
DepthFirstSearch dfs = new DepthFirstSearch();
List<Integer> dfsAnswer = dfs.depthFirstSearch(edges, n, src);
for(int node : dfsAnswer) {
System.out.print(node + " ");
}
}
}
C++ Code
#include<bits/stdc++.h>
using namespace std;
class DepthFirstSearch {
public:
vector<vector<int>> buildGraph(vector<vector<int>>& edges, int n) {
vector<vector<int>> graph(n);
for (const auto& edge : edges) {
graph[edge[0]].push_back(edge[1]);
graph[edge[1]].push_back(edge[0]);
}
return graph;
}
void solve(int node, vector<int>& dfsAnswer, vector<vector<int>>& graph, vector<bool>& visited) {
dfsAnswer.push_back(node);
visited[node] = true;
for (int nbr : graph[node]) {
if (!visited[nbr]) {
solve(nbr, dfsAnswer, graph, visited);
}
}
}
vector<int> depthFirstSearch(vector<vector<int>>& edges, int n, int src) {
vector<vector<int>> graph = buildGraph(edges, n);
vector<int> dfsAnswer;
vector<bool> visited(n, false);
solve(src, dfsAnswer, graph, visited);
return dfsAnswer;
}
};
int main() {
vector<vector<int>> edges = {{0, 1}, {0, 2}, {1, 2}, {1, 3}, {1, 4}, {2, 5}, {3, 4}, {3, 5}};
int n = 6;
int src = 2;
DepthFirstSearch dfs;
vector<int> dfsAnswer = dfs.depthFirstSearch(edges, n, src);
for (int node : dfsAnswer) {
cout << node << " ";
}
return 0;
}
Python Code
from typing import List
class DepthFirstSearch:
def __init__(self):
pass
def build_graph(self, edges, n):
graph = []
for i in range(n):
graph.append(list())
for edge in edges:
graph[edge[0]].append(edge[1])
graph[edge[1]].append(edge[0])
return graph
def solve(self, node, dfs_answer, graph, visited):
dfs_answer.append(node)
visited[node] = True
for nbr in graph[node]:
if not visited[nbr]:
self.solve(nbr, dfs_answer, graph, visited)
def depthFirstSearch(self, edges, n, src):
graph = self.build_graph(edges, n)
dfs_answer = []
visited = [False] * n
self.solve(src, dfs_answer, graph, visited)
return dfs_answer
if __name__ == "__main__":
edges = [[0, 1], [0, 2], [1, 2], [1, 3], [1, 4], [2, 5], [3, 4], [3, 5]]
n = 6
src = 2
dfs = DepthFirstSearch()
dfs_answer = dfs.depthFirstSearch(edges, n, src)
for node in dfs_answer:
print(node, end=" ")
Javascript Code
class DepthFirstSearch {
buildGraph(edges, n) {
const graph = new Array(n).fill(null).map(() => []);
for (const edge of edges) {
graph[edge[0]].push(edge[1]);
graph[edge[1]].push(edge[0]);
}
return graph;
}
solve(node, dfsAnswer, graph, visited) {
dfsAnswer.push(node);
visited[node] = true;
for (const nbr of graph[node]) {
if (!visited[nbr]) {
this.solve(nbr, dfsAnswer, graph, visited);
}
}
}
depthFirstSearch(edges, n, src) {
const graph = this.buildGraph(edges, n);
const dfsAnswer = [];
const visited = new Array(n).fill(false);
this.solve(src, dfsAnswer, graph, visited);
return dfsAnswer;
}
}
const edges = [[0, 1], [0, 2], [1, 2], [1, 3], [1, 4], [2, 5], [3, 4], [3, 5]];
const n = 6;
const src = 2;
const dfs = new DepthFirstSearch();
const dfsAnswer = dfs.depthFirstSearch(edges, n, src);
console.log(dfsAnswer.join(" "));
Go Code
package main
import "fmt"
type DepthFirstSearch struct{}
func (dfs *DepthFirstSearch) buildGraph(edges [][]int, n int) [][]int {
graph := make([][]int, n)
for i := 0; i < n; i++ {
graph[i] = make([]int, 0)
}
for _, edge := range edges {
graph[edge[0]] = append(graph[edge[0]], edge[1])
graph[edge[1]] = append(graph[edge[1]], edge[0])
}
return graph
}
func (dfs *DepthFirstSearch) solve(node int, dfsAnswer *[]int, graph [][]int, visited []bool) {
*dfsAnswer = append(*dfsAnswer, node)
visited[node] = true
for _, nbr := range graph[node] {
if !visited[nbr] {
dfs.solve(nbr, dfsAnswer, graph, visited)
}
}
}
func (dfs *DepthFirstSearch) depthFirstSearch(edges [][]int, n, src int) []int {
graph := dfs.buildGraph(edges, n)
dfsAnswer := make([]int, 0)
visited := make([]bool, n)
dfs.solve(src, &dfsAnswer, graph, visited)
return dfsAnswer
}
func main() {
edges := [][]int{{0, 1}, {0, 2}, {1, 2}, {1, 3}, {1, 4}, {2, 5}, {3, 4}, {3, 5}}
n := 6
src := 2
var dfs DepthFirstSearch
dfsAnswer := dfs.depthFirstSearch(edges, n, src)
for _, node := range dfsAnswer {
fmt.Printf("%d ", node)
}
}
Complexity Analysis
Time Complexity: O(V + E), where V is the total number of vertices and E is the number of edges.
Space Complexity: O(V + E), where V is the total number of vertices and E is the number of edges.