Clone Graph

To solve this coding challenge, we will implement a function to deep copy an undirected graph. The graph is represented using an adjacency list, and each node in the graph has a value and a list of neighbor nodes. Our goal is to return a deep copy of the graph, meaning that each node and its connections will be duplicated without sharing any reference with the original graph.

Explanation

In this challenge, we need to ensure that each node and its corresponding neighbors are copied correctly in such a way that the copied graph is identical to the original graph but without any shared references. We will employ Depth-First Search (DFS) to traverse the graph and clone each node. A crucial part of this process is maintaining a map (or dictionary) to record which original nodes have already been cloned, thus preventing infinite loops due to the cyclic nature of graphs. Here’s a step-by-step breakdown of our approach:
  1. Check for the Null Input:
    • If the input node is
      null
      , we immediately return
      null
      since there is no graph to clone.
  2. Use a Dictionary to Keep Track:
    • We use a dictionary named
      visited
      to map each original node to its clone. This helps to avoid re-cloning the same node and keeps track of already visited nodes.
  3. Depth-First Search (DFS) function:
    • We define a recursive DFS function that will:
    • Check if the current node has already been cloned by looking it up in the
      visited
      dictionary.
    • If it is already cloned, return the clone from the dictionary.
    • If it is not yet cloned, create a new node, add it to the
      visited
      dictionary, and then recursively clone all its neighbors.
  4. Clone the Graph:
    • Use the DFS function to start cloning from the given initial node.
    Below is the pseudocode, including comments to explain each step:
                                                
    # Function to clone the graph
    function cloneGraph(node):
    # If the given node is null, return null as there is no graph to clone
    if node is null:
    return null
    
    # Dictionary to keep track of visited nodes and their clones
    visited = dictionary()
    
    # Depth-First Search (DFS) function to clone the graph
    function DFS(currentNode):
    # If the current node is already visited, return its clone from visited dictionary
    if currentNode in visited:
    return visited[currentNode]
    
    # Create a clone for the current node
    clonedNode = Node(currentNode.val)
    # Add the cloned node to the visited dictionary
    visited[currentNode] = clonedNode
    
    # Iterate through all the neighbors of the current node
    for neighbor in currentNode.neighbors:
    # Recursively clone the neighbors and add them to the clone's neighbors list
    clonedNode.neighbors.append(DFS(neighbor))
    
    # Return the cloned node
    return clonedNode
    
    # Start cloning process from the input node using DFS
    return DFS(node)
    
                                            

    Detailed Steps in Pseudocode

  5. Initialization:
    • Begin by checking if the provided
      node
      is
      null
      . If it is, return
      null
      .
  6. Dictionary Setup:
    • Initialize an empty dictionary called
      visited
      which will store mappings from original nodes to their clones.
  7. Define DFS Function:
    • This function takes a
      currentNode
      .
    • If
      currentNode
      exists in
      visited
      , it means the node is already cloned, so return the corresponding clone from the dictionary.
    • If not, create a new node (
      clonedNode
      ) with the same value as
      currentNode
      .
    • Add the new
      clonedNode
      to the
      visited
      dictionary with
      currentNode
      as the key.
    • For each neighbor of
      currentNode
      , call DFS recursively and append the result to the
      clonedNode
      's neighbors list.
    • Return the
      clonedNode
      .
  8. Start DFS Cloning:
    • Call the DFS function with the initial input
      node
      and return the result.
By carefully managing the
visited
dictionary, we ensure each node is only cloned once, efficiently handling cycles in the graph while maintaining the structure and connections of the original graph in the newly cloned graph.