Bird
Raised Fist0
DSA Typescriptprogramming~20 mins

DFS Depth First Search on Graph in DSA Typescript - Practice Problems & Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
DFS Mastery Badge
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of DFS traversal on a simple graph
What is the output of the following DFS traversal starting from node 0?
DSA Typescript
const graph = new Map<number, number[]>([
  [0, [1, 2]],
  [1, [3]],
  [2, []],
  [3, []]
]);

function dfs(node: number, visited: Set<number>, graph: Map<number, number[]>, result: number[]) {
  visited.add(node);
  result.push(node);
  for (const neighbor of graph.get(node) || []) {
    if (!visited.has(neighbor)) {
      dfs(neighbor, visited, graph, result);
    }
  }
}

const visited = new Set<number>();
const result: number[] = [];
dfs(0, visited, graph, result);
console.log(result.join(' -> ') + ' -> null');
A0 -> 2 -> 1 -> 3 -> null
B0 -> 1 -> 3 -> 2 -> null
C0 -> 1 -> 2 -> 3 -> null
D0 -> 3 -> 1 -> 2 -> null
Attempts:
2 left
💡 Hint
Remember DFS explores as far as possible along each branch before backtracking.
🧠 Conceptual
intermediate
1:30remaining
Number of nodes visited in DFS
Given the graph below, how many nodes will DFS visit starting from node 2?
DSA Typescript
const graph = new Map<number, number[]>([
  [0, [1]],
  [1, [2]],
  [2, [3]],
  [3, []],
  [4, [0]]
]);
A2
B4
C1
D3
Attempts:
2 left
💡 Hint
DFS visits all reachable nodes from the start node.
❓ Predict Output
advanced
2:30remaining
DFS traversal order with cycle in graph
What is the output of the DFS traversal starting from node 0 in the graph with a cycle?
DSA Typescript
const graph = new Map<number, number[]>([
  [0, [1]],
  [1, [2]],
  [2, [0, 3]],
  [3, []]
]);

function dfs(node: number, visited: Set<number>, graph: Map<number, number[]>, result: number[]) {
  visited.add(node);
  result.push(node);
  for (const neighbor of graph.get(node) || []) {
    if (!visited.has(neighbor)) {
      dfs(neighbor, visited, graph, result);
    }
  }
}

const visited = new Set<number>();
const result: number[] = [];
dfs(0, visited, graph, result);
console.log(result.join(' -> ') + ' -> null');
A0 -> 2 -> 1 -> 3 -> null
B0 -> 1 -> 3 -> 2 -> null
C0 -> 1 -> 2 -> 3 -> null
D0 -> 3 -> 2 -> 1 -> null
Attempts:
2 left
💡 Hint
DFS avoids revisiting nodes already visited to prevent infinite loops.
🔧 Debug
advanced
2:30remaining
Identify the error in DFS implementation
What error will the following DFS code produce when run on the given graph?
DSA Typescript
const graph = new Map<number, number[]>([
  [0, [1]],
  [1, [2]],
  [2, []]
]);

function dfs(node: number, visited: Set<number>, graph: Map<number, number[]>, result: number[]) {
  if (visited.has(node)) return;
  result.push(node);
  for (const neighbor of graph.get(node)!) {
    dfs(neighbor, visited, graph, result);
  }
}

const visited = new Set<number>();
const result: number[] = [];
dfs(0, visited, graph, result);
console.log(result.join(' -> ') + ' -> null');
ARuntime error: Maximum call stack size exceeded
BThe code runs correctly and outputs '0 -> 1 -> 2 -> null'
CTypeError: Cannot read property 'Symbol.iterator' of undefined
DThe output is '0 -> 1 -> null'
Attempts:
2 left
💡 Hint
Check if the visited set is updated properly to avoid infinite recursion.
🚀 Application
expert
3:00remaining
DFS to find all connected components count
Given the graph below, what is the number of connected components?
DSA Typescript
const graph = new Map<number, number[]>([
  [0, [1]],
  [1, [0]],
  [2, [3]],
  [3, [2]],
  [4, []]
]);

function dfs(node: number, visited: Set<number>, graph: Map<number, number[]>) {
  visited.add(node);
  for (const neighbor of graph.get(node) || []) {
    if (!visited.has(neighbor)) {
      dfs(neighbor, visited, graph);
    }
  }
}

const visited = new Set<number>();
let count = 0;
for (const node of graph.keys()) {
  if (!visited.has(node)) {
    dfs(node, visited, graph);
    count++;
  }
}
console.log(count);
A3
B2
C1
D4
Attempts:
2 left
💡 Hint
Each connected component is a group of nodes reachable from each other.

Practice

(1/5)
1. What is the main idea behind Depth First Search (DFS) on a graph?
easy
A. Explore as far as possible along each branch before backtracking
B. Visit all neighbors of a node before moving deeper
C. Visit nodes in order of their distance from the start node
D. Randomly visit nodes until all are visited

Solution

  1. Step 1: Understand DFS traversal strategy

    DFS explores nodes by going deep into one branch before backtracking to explore other branches.
  2. Step 2: Compare with other traversal methods

    BFS visits neighbors first, but DFS goes deep first, matching Explore as far as possible along each branch before backtracking.
  3. Final Answer:

    Explore as far as possible along each branch before backtracking -> Option A
  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 neighbors first
  • Assuming DFS visits nodes by distance
2. Which of the following is the correct TypeScript function signature for a DFS function on a graph represented as an adjacency list?
easy
A. function dfs(graph: Map, start: number): void
B. function dfs(graph: number[], start: number): void
C. function dfs(graph: number[][], start: number): void
D. function dfs(graph: string[][], start: string): void

Solution

  1. Step 1: Identify graph representation type

    An adjacency list for a graph with numbered nodes is usually number[][], where each index holds neighbors.
  2. Step 2: Check parameter types

    Start node is a number, so function signature with graph: number[][] and start: number is correct.
  3. Final Answer:

    function dfs(graph: number[][], start: number): void -> Option C
  4. Quick Check:

    Adjacency list = number[][], start node = number [OK]
Hint: Adjacency list uses array of arrays for neighbors [OK]
Common Mistakes:
  • Using number[] instead of number[][] for adjacency list
  • Using Map with incorrect value type
  • Using string types for numeric graphs
3. What is the output of the following DFS traversal starting from node 0?
const graph = [[1, 2], [2], [0, 3], [3]];
const visited: boolean[] = [];
const result: number[] = [];
function dfs(node: number) {
  if (visited[node]) return;
  visited[node] = true;
  result.push(node);
  for (const neighbor of graph[node]) {
    dfs(neighbor);
  }
}
dfs(0);
console.log(result);
medium
A. [0, 2, 3, 1]
B. [0, 2, 1, 3]
C. [0, 1, 2]
D. [0, 1, 2, 3]

Solution

  1. Step 1: Start DFS at node 0

    Visit 0, mark visited, add to result: [0]. Neighbors: 1, 2.
  2. Step 2: Visit neighbor 1

    Visit 1, mark visited, add: [0,1]. Neighbor: 2.
  3. Step 3: Visit neighbor 2 from 1

    Visit 2, mark visited, add: [0,1,2]. Neighbors: 0 (visited), 3.
  4. Step 4: Visit neighbor 3 from 2

    Visit 3, mark visited, add: [0,1,2,3]. Neighbor: 3 (already visited).
  5. Final Answer:

    [0, 2, 1, 3] -> Option B
  6. Quick Check:

    DFS order = [0,2,1,3] [OK]
Hint: Follow neighbors recursively, mark visited to avoid repeats [OK]
Common Mistakes:
  • Not marking nodes visited before recursion
  • Visiting neighbors in wrong order
  • Ignoring already visited nodes
4. Identify the bug in this DFS implementation and choose the fix:
function dfs(node: number, graph: number[][], visited: boolean[]) {
  visited[node] = true;
  for (const neighbor of graph[node]) {
    if (!visited[neighbor]) {
      dfs(neighbor, graph, visited);
    }
  }
}

const graph = [[1], [2], [0]];
const visited = new Array(graph.length).fill(false);
dfs(0, graph, visited);
console.log(visited);
medium
A. Mark visited[node] = true after recursive calls
B. Initialize visited array with true instead of false
C. Add a base case to return if node is already visited at start
D. No bug, code works correctly

Solution

  1. Step 1: Check visited marking timing

    Visited[node] is marked true before recursion, preventing revisits.
  2. Step 2: Verify recursion and base case

    Recursion only happens if neighbor not visited, so no infinite loops.
  3. Final Answer:

    No bug, code works correctly -> Option D
  4. Quick Check:

    Visited marked before recursion = correct DFS [OK]
Hint: Mark visited before recursion to avoid cycles [OK]
Common Mistakes:
  • Marking visited after recursion causing infinite loops
  • Initializing visited array incorrectly
  • Missing base case check
5. Given a graph with possible cycles, how can you modify DFS to detect if a cycle exists starting from a given node? Choose the best approach.
hard
A. Use a recursion stack array to track nodes in the current path and detect back edges
B. Only mark nodes visited after all neighbors are visited
C. Use BFS instead of DFS to detect cycles
D. Ignore visited nodes and continue traversal

Solution

  1. Step 1: Understand cycle detection in DFS

    Detecting cycles requires knowing if a node is in the current recursion path (stack).
  2. Step 2: Use recursion stack tracking

    Maintain a separate array to track nodes currently in recursion; if a neighbor is in this stack, a cycle exists.
  3. Step 3: Evaluate other options

    Marking visited after neighbors or using BFS won't reliably detect cycles; ignoring visited nodes causes infinite loops.
  4. Final Answer:

    Use a recursion stack array to track nodes in the current path and detect back edges -> Option A
  5. Quick Check:

    Cycle detection = recursion stack tracking [OK]
Hint: Track recursion path to find back edges indicating cycles [OK]
Common Mistakes:
  • Not tracking recursion stack causing missed cycles
  • Using BFS which doesn't track recursion path
  • Marking visited too late or ignoring visited nodes
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