Detect Cycle in an Undirected Graph
Read the edges in list order and keep the vertices in groups with Union-Find. If an edge joins two vertices that are already in one group, that edge closes a cycle, so return true. Every other edge just merges two groups.
Two vertices with the same root are already joined by a path of edges read so far, so an edge between them closes a cycle.
Problem
You get an undirected graph with V vertices, numbered 0 to V − 1, and a list of E edges. Each entry edges[i] = [u, v] is one edge joining vertices u and v. Each edge is listed once.
Return true if the graph contains a cycle, and false if it does not. The graph may have several separate pieces, and some of them may not touch vertex 0.
V, the number of vertices, and edges, the list of edges.
true if the graph has a cycle, otherwise false.
Vertices 0, 1 and 2 form a triangle: 0 → 1 → 2 → 0 comes back to the start.
The edges form one path, and a path has no cycle.
- • 1 ≤ V, E ≤ 10^5
- • 0 ≤ edges[i][0], edges[i][1] < V
First, think yourself
Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.
- 1.
A cycle means I can leave a vertex and come back to it without reusing an edge. How can I tell whether two vertices are already joined by a path?
- 2.
If I add the edges one at a time, when does a new edge create a cycle?
- 3.
Can an edge that joins two different pieces ever close a loop?
- 4.
If the graph has at least V edges, must it contain a cycle? What can I say about a graph with fewer edges?
- 5.
Do I need to search from every vertex, or can I decide while reading the list?
Brute force approach
Optimized approach
Why does this algorithm work?
Dry run
All approaches compared
| Approach | Idea | Time | Space |
|---|---|---|---|
| Brute Force | Remove one edge; if its ends are still joined, it was on a cycle | O(E · (V + E)) | O(V + E) |
| Optimal | Union the edges in list order; the first edge whose ends already share a root closes a cycle | O(E · α(V)) | O(V) |
Why does this belong to this pattern?
- “undirected graph”Edges have no arrows, so an edge only links two groups and direction does not matter.
- “contains a cycle”A cycle is an edge whose two ends are already linked, so find the first such edge.
- “a list of E edges”Each edge is read once, in list order, so one pass decides the answer.
The question is about groups, not about how far apart two vertices are, so Union-Find fits. The first edge whose two ends already share a root is a cycle. This is the basic cycle problem: Redundant Connection and Redundant Connection II use the same unite call. Direction changes the answer, though. In 0→1, 0→2, 1→2 there is no cycle, but Union-Find sees 1 and 2 already joined and reports one. Directed graphs need Topological Sort instead.
Don't make this mistake
On the single edge [[0, 1]] with V = 2, dfs(0) visits 1, and then 1 sees 0 already visited, so the wrong code says true. But one edge is a tree. In an undirected graph the edge you came in by always looks visited, so you must skip the parent. The plain visited rule belongs to directed graphs.
A forest on V vertices has at most V − 1 edges, so E ≥ V does prove a cycle. But E < V proves nothing when the graph has several pieces. Triangle 0–1–2 plus the lone vertices 3 and 4 has V = 5 and E = 3, and it still has a cycle, so the count wrongly says false.
After a successful unite, the two ends always share a root, so the check fires on the very first edge. Even the single edge [[0, 1]], which has no cycle, returns true. Ask whether the ends are already joined before you merge them.
Want to implement this?
Write it yourself on GeeksforGeeks, then come back and compare your code with the solutions above.
Open coding workspaceHow this concept connects to System Design & C++ Systems
Top engineering interviews test whether you understand how algorithms like Union-Find (DSU) translate into production architectures and low-level memory mechanics.
Foundations: Object-Oriented Principles in C++23
Class invariants, pure virtual interfaces, and RAII smart pointers.
Food Delivery System (Zomato Architecture)
Real-world machine coding application of algorithms and design patterns.
Pointers vs References Deep Dive
Pointer arithmetic and memory layout under the hood.
Virtual Method Table (vtable) & Memory Layout
Polymorphism, vptr overhead, and multiple inheritance in memory.