133. Clone Graph

2019/11/19 Leetcode

133. Clone Graph

Tags: ‘Depth-first Search’, ‘Breadth-first Search’, ‘Graph’

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 val (int) and a list (List[Node]) of its neighbors.

 

Example:

Input:
{"$id":"1","neighbors":[{"$id":"2","neighbors":[{"$ref":"1"},{"$id":"3","neighbors":[{"$ref":"2"},{"$id":"4","neighbors":[{"$ref":"3"},{"$ref":"1"}],"val":4}],"val":3}],"val":2},{"$ref":"4"}],"val":1}

Explanation:
Node 1's value is 1, and it has two neighbors: Node 2 and 4.
Node 2's value is 2, and it has two neighbors: Node 1 and 3.
Node 3's value is 3, and it has two neighbors: Node 2 and 4.
Node 4's value is 4, and it has two neighbors: Node 1 and 3.

 

Note:

  1. The number of nodes will be between 1 and 100.
  2. The undirected graph is a simple graph, which means no repeated edges and no self-loops in the graph.
  3. Since the graph is undirected, if node p has node q as neighbor, then node q must have node p as neighbor too.
  4. You must return the copy of the given node as a reference to the cloned graph.

Solution

方法1: DFS Recursive, 用Map记录已经copy过的node $O(V * n) time O(V) space$ where n is average number of edges for each node

class Solution {
    public Node cloneGraph(Node node) {
        if (node == null) return null;
        
        Map<Node, Node> map = new HashMap<>(); // map from origin to clone
        Node copy = new Node(node.val, new ArrayList<Node>());
        map.put(node, copy);
        
        for (Node neighbor: node.neighbors) {
            copy.neighbors.add(clone(neighbor, map));
        }
        return copy;
    }
    
    private Node clone(Node node, Map<Node, Node> map) {
        if (map.containsKey(node)) {
            return map.get(node);
        }
        Node copy = new Node(node.val, new ArrayList<Node>());
        map.put(node, copy);
        for (Node neighbor: node.neighbors) {
            copy.neighbors.add(clone(neighbor, map));
        }
        return copy;
    }
}

方法2: BFS using Queue, 同样需要Map来记录每个Node和它的copy

class Solution {
    public Node cloneGraph(Node node) {
        if (node == null) return null;
        
        Node copy = new Node(node.val, new ArrayList<Node>()); 
        Map<Node, Node> map = new HashMap<>(); // visited node and its copy
        map.put(node, copy);
        Queue<Node> queue = new LinkedList<>(); // unvisited node
        queue.add(node);
        
        while (!queue.isEmpty()) {
            Node n = queue.poll();
            for (Node neighbor: n.neighbors) {
                if (!map.containsKey(neighbor)) {
                    Node neighborCopy = new Node(neighbor.val, new ArrayList<Node>());
                    map.put(neighbor, neighborCopy);
                    queue.add(neighbor);
                }
                map.get(n).neighbors.add(map.get(neighbor)); // link copy to neighborCopy
            }
        }
        return copy;
    }
}

Search

    Table of Contents