Bird
Raised Fist0
DSA Javascriptprogramming~5 mins

DFS Depth First Search on Graph in DSA Javascript - Time & Space Complexity

Choose your learning style10 modes available
Time Complexity: DFS Depth First Search on Graph
O(n + e)
Understanding Time Complexity

We want to understand how the time taken by Depth First Search (DFS) grows as the graph size increases.

Specifically, how does DFS's work change when the graph has more nodes and edges?

Scenario Under Consideration

Analyze the time complexity of the following DFS code on a graph.


function dfs(graph, start, visited = new Set()) {
  visited.add(start);
  for (const neighbor of graph[start]) {
    if (!visited.has(neighbor)) {
      dfs(graph, neighbor, visited);
    }
  }
}
    

This code visits all nodes reachable from the start node using DFS traversal.

Identify Repeating Operations

Look at what repeats in this DFS code.

  • Primary operation: Visiting each node and checking its neighbors.
  • How many times: Each node is visited once, and each edge is checked once during traversal.
How Execution Grows With Input

As the graph grows, DFS visits every node and edge once.

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

Pattern observation: The work grows roughly with the sum of nodes and edges, so more nodes or edges means more work.

Final Time Complexity

Time Complexity: O(n + e)

This means DFS takes time proportional to the total number of nodes plus edges in the graph.

Common Mistake

[X] Wrong: "DFS always takes O(n²) time because it visits nodes multiple times."

[OK] Correct: DFS marks nodes as visited, so each node and edge is processed only once, avoiding repeated work.

Interview Connect

Understanding DFS time complexity helps you explain how graph traversals scale and why DFS is efficient for exploring connected parts of graphs.

Self-Check

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

Practice

(1/5)
1. What does DFS (Depth First Search) do when traversing a graph?
easy
A. It only visits nodes connected directly to the start node.
B. It visits nodes level by level from the start node.
C. It explores as far as possible along each branch before backtracking.
D. It randomly visits nodes without any order.

Solution

  1. Step 1: Understand DFS traversal

    DFS explores a path deeply before moving to another path.
  2. Step 2: Compare with other traversals

    BFS visits nodes level by level, but DFS goes deep first.
  3. Final Answer:

    It explores as far as possible along each branch before backtracking. -> Option C
  4. Quick Check:

    DFS = deep exploration first [OK]
Hint: DFS goes deep first, BFS goes wide first [OK]
Common Mistakes:
  • Confusing DFS with BFS
  • Thinking DFS visits nodes randomly
  • Assuming DFS only visits direct neighbors
2. Which of the following is the correct way to start a DFS function in JavaScript for a graph represented as adjacency list graph?
easy
A. function dfs(node, visited = new Set()) {
B. function dfs(node, visited = []) {
C. function dfs(node, visited = {}) {
D. function dfs(node, visited = 0) {

Solution

  1. Step 1: Identify suitable data structure for visited nodes

    A Set is ideal to track visited nodes efficiently.
  2. Step 2: Check function signature correctness

    Using visited = new Set() initializes visited nodes properly.
  3. Final Answer:

    function dfs(node, visited = new Set()) { -> Option A
  4. Quick Check:

    Use Set for visited nodes [OK]
Hint: Use Set to track visited nodes in DFS [OK]
Common Mistakes:
  • Using array or object incorrectly for visited
  • Initializing visited as a number
  • Not initializing visited parameter
3. Given the graph adjacency list:
const graph = {
  1: [2, 3],
  2: [4],
  3: [],
  4: []
};

function dfs(node, visited = new Set()) {
  visited.add(node);
  for (const neighbor of graph[node]) {
    if (!visited.has(neighbor)) {
      dfs(neighbor, visited);
    }
  }
  return Array.from(visited);
}

console.log(dfs(1));

What is the output?
medium
A. [1, 3, 2, 4]
B. [1, 4, 2, 3]
C. [1, 2, 3, 4]
D. [1, 2, 4, 3]

Solution

  1. Step 1: Start DFS from node 1

    Visit 1, then neighbors 2 and 3 in order.
  2. Step 2: Visit neighbors recursively

    From 2, visit 4. From 3, no neighbors. Order: 1, 2, 4, 3.
  3. Final Answer:

    [1, 2, 4, 3] -> Option D
  4. Quick Check:

    DFS order = 1,2,4,3 [OK]
Hint: Follow neighbors deeply before next sibling [OK]
Common Mistakes:
  • Visiting neighbors in wrong order
  • Confusing BFS order with DFS
  • Not converting Set to array properly
4. Find the error in this DFS code snippet for graph traversal:
const graph = {
  1: [2, 3],
  2: [4],
  3: [],
  4: []
};

function dfs(node, visited = new Set()) {
  visited.add(node);
  for (const neighbor of graph[node]) {
    if (visited.has(neighbor)) {
      dfs(neighbor, visited);
    }
  }
  return visited;
}

console.log(Array.from(dfs(1)));
medium
A. The condition should be if (!visited.has(neighbor)) instead of if (visited.has(neighbor))
B. The visited set should be an array instead
C. The graph object keys should be strings, not numbers
D. The function should return an array, not a set

Solution

  1. Step 1: Check the neighbor visit condition

    It incorrectly calls dfs if neighbor is already visited, causing infinite recursion.
  2. Step 2: Correct the condition

    Change to if (!visited.has(neighbor)) to visit unvisited neighbors only.
  3. Final Answer:

    The condition should be if (!visited.has(neighbor)) instead of if (visited.has(neighbor)) -> Option A
  4. Quick Check:

    Visit only unvisited neighbors [OK]
Hint: Call DFS only if neighbor not visited [OK]
Common Mistakes:
  • Calling DFS on already visited nodes
  • Using wrong data structure for visited
  • Returning wrong type from DFS
5. You want to find if there is a path from node 1 to node 5 in this graph:
const graph = {
  1: [2, 3],
  2: [4],
  3: [5],
  4: [],
  5: []
};

function dfs(node, target, visited = new Set()) {
  if (node === target) return true;
  visited.add(node);
  for (const neighbor of graph[node]) {
    if (!visited.has(neighbor)) {
      if (dfs(neighbor, target, visited)) return true;
    }
  }
  return false;
}

console.log(dfs(1, 5));

What will be the output and why?
hard
A. false, because the visited set is not updated correctly
B. true, because DFS finds a path 1 -> 3 -> 5
C. true, because DFS visits all nodes regardless of target
D. false, because node 5 is not directly connected to 1

Solution

  1. Step 1: Check DFS path search logic

    DFS returns true immediately when target node is found.
  2. Step 2: Trace path from 1 to 5

    Path exists: 1 -> 3 -> 5, so DFS returns true.
  3. Final Answer:

    true, because DFS finds a path 1 -> 3 -> 5 -> Option B
  4. Quick Check:

    DFS finds path = true [OK]
Hint: DFS returns true when target found [OK]
Common Mistakes:
  • Assuming direct connection needed
  • Ignoring early return on target found
  • Not updating visited set properly
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