my dsa gallery
GraphDFS / BFS with Parent Tracking

Detect Cycle in an Undirected Graph

Problem link: https://www.geeksforgeeks.org/problems/detect-cycle-in-an-undirected-graph/1

Problem Statement

Given an undirected graph with V vertices and E edges, check whether it contains any cycle or not. The graph is represented using an adjacency list.

Input

An adjacency list adj and the number of vertices V.

Output

Boolean (true if cycle exists, false otherwise).

Example

Input: V = 5, E = 5, adj = [[1], [0, 2, 4], [1, 3], [2, 4], [1, 3]] Output: true Explanation: Node 1, 2, 3, 4 form a cycle.

Explanation

In this graph, starting from node 1, we can travel through 2, 3, and 4 and return to 1. This circular path indicates a cycle.

Brute Force

Intuition

For every node, try to see if there is a path back to itself without immediately reversing the last edge taken.

Approach

Check all possible paths using a simple recursion. However, since this is a graph, we must use a visited array to avoid infinite loops. The standard way to implement this is either BFS or DFS.

Dry Run

V=3, E=3 (0-1, 1-2, 2-0)

  1. Visit 0, mark visited.
  2. Move to 1, mark visited, parent is 0.
  3. Move to 2, mark visited, parent is 1.
  4. Check neighbors of 2: 1 (parent, skip), 0 (visited and not parent! Cycle found).

Code (Java)

class Solution {
    // Standard DFS/BFS implementation is already optimal.
}
Time: O(V + E)Space: O(V)

Complexity Analysis

We visit every vertex and edge once.

Optimal Solution

Intuition

We use DFS or BFS and keep track of the parent node (the node we just came from). If we reach a node that has already been visited and is NOT the parent of our current node, it means there's another path to that node, hence a cycle.

Approach

  1. Initialize a visited array of size V with false.
  2. Since the graph might have multiple components, loop through all vertices i from 0 to V-1.
  3. If node i is not visited, call the isCycleDFS(i, -1) function.
  4. In isCycleDFS(node, parent):
    • Mark node as visited.
    • For every neighbor adjNode of node:
      • If adjNode is not visited, recursively call isCycleDFS(adjNode, node). If it returns true, return true.
      • Else if adjNode is visited AND adjNode != parent, return true (cycle found).
  5. If no cycle is found in any component, return false.
Step 1 of 1- DFS Step
Tracking the node and its source (parent)
Loading...
Use arrow keys to navigate

Dry Run

adj = [[1, 2], [0, 2], [0, 1]]

  1. DFS(0, -1): visited={0}
  2. Neighbor 1: DFS(1, 0), visited={0, 1}
  3. Neighbor 0 of node 1: 0 is parent, skip.
  4. Neighbor 2 of node 1: DFS(2, 1), visited={0, 1, 2}
  5. Neighbor 0 of node 2: 0 is visited and 0 != parent(1). Cycle detected!

Code (Java)

Time: O(V + 2E)Space: O(V)

Complexity Analysis

Time: We traverse each node once and check each edge (twice for undirected graphs). Space: Visited array and recursion stack both take O(V).

Quick Revision (Brute Force)

  • Traverse graph components
  • O(V+E) time

Quick Revision (Optimal)

  • DFS or BFS with Parent tracking
  • Condition: (visited[neighbor] == true && neighbor != parent)
  • Handles disconnected components with a loop
  • O(V+E) time, O(V) space

Study Photos

Upload screenshots/notes for this specific problem.

Drag & drop or click to select
Drop an image anywhere in this box to upload.
No photos uploaded till now.

Comments

Stored in D1. Login required.
  • If we see a visited node that is not our parent, it means there is another way to reach that node. That's a cycle.
    2026-04-16T12:40:41.753Z