Skip to main content
  1. LeetCode/

LeetCode 1971: Find if Path Exists in Graph

·2 mins· ·
LeetCode Easy Graph Union-Find
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: easy First Attempt: 2026-04-08 Source: Day 2 learning note

Study Context
#

This article is rebuilt from the exact LeetCode section in the learning note. I kept the note’s repair points, comparison points, and common mistakes, while removing unrelated non-LeetCode material from the same day.

Learning Note Extract
#

LC 1971 — Find if Path Exists in Graph
#

  • Pattern: BFS/DFS OR Union-Find

  • Critical: This is an undirected graph — add both directions when building adjacency list

  • BFS approach: Standard BFS from source. Return true if destination is reached.

  • Union-Find approach: Group all connected nodes. Return find(source) == find(destination)

  • Common bugs:

    1. Building directed adjacency list for undirected graph
    2. Applying Kahn’s in-degree logic to undirected graph — in-degree is meaningless here
    3. Never calling union on edges — nodes stay in separate components
    4. Calling union(x, y) with raw nodes instead of roots union(find(x), find(y))
    5. Wrong rank increment — only increment when two trees of equal rank merge
  • Union-Find template:

parent = [i for i in range(n)]
rank = [0] * n

def find(x):
    if parent[x] != x:
        parent[x] = find(parent[x])  # path compression
    return parent[x]

def union(x, y):
    rx, ry = find(x), find(y)
    if rx == ry:
        return
    if rank[rx] > rank[ry]:
        parent[ry] = rx
    elif rank[rx] < rank[ry]:
        parent[rx] = ry
    else:
        parent[rx] = ry
        rank[ry] += 1
  • Trade-off: BFS = simpler, good for single query. Union-Find = better for multiple path queries on same graph (near O(1) per query after O(V+E) build).

Clean Solution
#

The note above captures the reasoning and the mistakes to avoid. The implementation below is the version I would submit.

from typing import List

class Solution:
    def validPath(self, n: int, edges: List[List[int]], source: int, destination: int) -> bool:
        parent = list(range(n))
        rank = [0] * n

        def find(x):
            while parent[x] != x:
                parent[x] = parent[parent[x]]
                x = parent[x]
            return x

        def union(a, b):
            ra, rb = find(a), find(b)
            if ra == rb:
                return
            if rank[ra] < rank[rb]:
                ra, rb = rb, ra
            parent[rb] = ra
            if rank[ra] == rank[rb]:
                rank[ra] += 1

        for a, b in edges:
            union(a, b)

        return find(source) == find(destination)

Complexity
#

Time O((n+e) alpha(n)), Space O(n).

Mistakes To Watch
#

  • Treating the graph as directed.
  • Forgetting path compression / union is enough for connectivity.

Final Interview Explanation
#

Start from the state definition, then explain why the transition preserves that state. If there is a loop direction, state compression, or a similar-looking problem with a different answer shape, call that out explicitly because that is where this problem family usually breaks down.

Related

LeetCode 207: Course Schedule
·2 mins
LeetCode Medium Graph Topological-Sort
LeetCode note for Course Schedule, rebuilt from the original learning note
LeetCode 210: Course Schedule II
·2 mins
LeetCode Medium Graph Topological-Sort
LeetCode note for Course Schedule II, rebuilt from the original learning note
LeetCode 2192: All Ancestors of a Node in a DAG
·3 mins
LeetCode Medium Graph Topological-Sort
LeetCode note for All Ancestors of a Node in a DAG, rebuilt from the original learning note
LeetCode 496: Next Greater Element I (Monotonic Stack)
·2 mins
LeetCode Daily Easy Array Stack Monotonic-Stack Hash-Map Next-Greater-Element
Monotonic decreasing stack over nums2 to build next-greater map; answer queries for nums1.
LeetCode 20: Valid Parentheses
·2 mins
LeetCode Daily Easy String Stack Data-Structures Parentheses Validation
Solving the Valid Parentheses problem using stack-based approach
LeetCode 1071: Greatest Common Divisor of Strings
·2 mins
LeetCode Daily Easy String Gcd Math
LeetCode Problem Solving