Written by Prashant Basnet
👋 Welcome to my Signature, a space between logic and curiosity.
I’m a Software Development Engineer who loves turning ideas into systems that work beautifully.
This space captures the process: the bugs, breakthroughs, and “aha” moments that keep me building.
Imagine you're building a social network, and you need to create a test environment that perfectly mirrors your production network - every user, every connection, every relationship.
Or picture yourself developing a game where you need to save the entire game state, including all the interconnected objects and their relationships. These are real-world scenarios where understanding graph cloning becomes crucial.
The Clone Graph problem asks us to create a perfect copy of a connected structure - not just the surface-level data, but all the deep relationships between elements.
What makes this problem fascinating is its deceptive simplicity. At first glance, it might seem as easy as copying nodes one by one.
But what happens when Node A points to Node B, which points back to Node A?
This problem tests our understanding of:
A leetcode problem of graph copy:
Given a reference of a node in a connected undirected graph.
Return a deep copy (clone) of the graph.
Each node in the graph contains a value (int) and a list (List[Node]) of its neighbors.
class Node {
public int val; public List<Node> neighbors; }Test case format:
For simplicity, each node's value is the same as the node's index (1-indexed). For example, the first node with val == 1, the second node with val == 2, and so on. The graph is represented in the test case using an adjacency list.
An adjacency list is a collection of unordered lists used to represent a finite graph. Each list describes the set of neighbors of a node in the graph.
The given node will always be the first node with val = 1. You must return the copy of the given node as a reference to the cloned graph.
Example 1:
Let's understand how we can solve it?
Let's see how the map fills up during DFS:
Start at node 1:
map = { node1 -> newNode1 // Maps original node1 to its clone }Process node 1's neighbors (2,4):
map = { node1 -> newNode1 node2 -> newNode2 // Added when processing node 1's first neighbor }When processing node 2's neighbour's (1,3):
map = { node1 -> newNode1 node2 -> newNode2 node3 -> newNode3 }This continues until all nodes are processed
map = { node1 -> newNode1 node2 -> newNode2 node3 -> newNode3 node4 -> newNode4 }/** * // Definition for a Node. * class Node { * constructor(val = 0, neighbors = []) { * this.val = val; * this.neighbors = neighbors; * } * } */class Solution { /** * @param {Node} node * @return {Node} */ constructor(){ this.map = new Map() } cloneGraph(node) { if(!node){ return null } if(this.map.has(node)){ return this.map.get(node) } let cloneNode = new Node(node.val) this.map.set(node, cloneNode) for(let neighbor of node.neighbors){ cloneNode.neighbors.push(this.cloneGraph(neighbor)) } return cloneNode } }#graphs #datastructures #cloningGraphs #leetcode