↓Skip to main content
  1. LeetCode/

LeetCode 133: Clone Graph

·1 min· ·
LeetCode Medium Hash-Table Depth-First-Search Breadth-First-Search Graph
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: medium First Attempt: 2022-10-30

  • Submissions: Runtime Error ×7 → Accepted ×2

Approach
#

Deep-copy a possibly cyclic graph: dfs(node) returns the stored copy if one exists; otherwise it creates a node, stores it first, then recursively copies the neighbors (Hash Table; BFS works too). Storing before recursing is what handles cycles. An empty input returns None.

My Attempts
#

The early versions had syntax errors and no empty-graph check: with a None input they read node.val (AttributeError). One version was otherwise correct but missed if not node as well; adding it passed.

Solution
#

class Solution:
    def cloneGraph(self, node: Optional['Node']) -> Optional['Node']:
        if not node:
            return None
        copies = {}
        def dfs(cur):
            if cur in copies:
                return copies[cur]
            copy = Node(cur.val)
            copies[cur] = copy
            copy.neighbors = [dfs(nb) for nb in cur.neighbors]
            return copy
        return dfs(node)

Complexity
#

Time O(V + E), space O(V).

Mistakes to Avoid
#

  • Store the new node before recursing, or cycles recurse forever.
  • Return None for an empty graph.

Interview Explanation
#

DFS with a hash map from old nodes to copies: I store each new node before copying its neighbors, so cycles find the existing copy, and an empty graph returns None. Time O(V + E).

Related

LeetCode 417: Pacific Atlantic Water Flow
·3 mins
LeetCode Medium Array Depth-First-Search Breadth-First-Search Matrix
LeetCode 417 note: walk inward from each ocean’s shore to cells no lower than the current one; cells reached from both oceans are the answer
LeetCode 695: Max Area of Island
·2 mins
LeetCode Medium Array Depth-First-Search Breadth-First-Search Union-Find
LeetCode 695 note: DFS each unvisited 1 to measure its island and keep the maximum; cells are the integer 1, not a string
LeetCode 1448: Count Good Nodes in Binary Tree
·1 min
LeetCode Medium Tree Depth-First-Search Breadth-First-Search Binary-Tree
LeetCode 1448 note: pass the path maximum down during DFS; a node is good when its value is at least that maximum
LeetCode 199: Binary Tree Right Side View
·1 min
LeetCode Medium Tree Depth-First-Search Breadth-First-Search Binary-Tree
LeetCode 199 note: in a level-order traversal, each level’s rightmost node is what you see from the right
LeetCode 102: Binary Tree Level Order Traversal
·1 min
LeetCode Medium Tree Breadth-First-Search Binary-Tree
LeetCode 102 note: BFS one whole level at a time, building the next level from the current one; an empty tree returns an empty list
LeetCode 105: Construct Binary Tree from Preorder and Inorder Traversal
·2 mins
LeetCode Medium Array Hash-Table Divide-and-Conquer Tree
LeetCode 105 note: the first pre-order value is the root, and its position in the in-order tells the left subtree’s size; look positions up in a dictionary for O(n)