133. Clone Graph

Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.

OJ's undirected graph serialization:
Nodes are labeled uniquely.
We use # as a separator for each node, and , as a separator for node label and each neighbor of the node.
As an example, consider the serialized graph {0,1,2#1,2#2,2}.
The graph has a total of three nodes, and therefore contains three parts as separated by #.
First node is labeled as 0. Connect node 0 to both nodes 1 and 2.
Second node is labeled as 1. Connect node 1 to node 2.
Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.
Visually, the graph looks like the following:

       1
      / \
     /   \
    0 --- 2
         / \
         \_/

Solution1:遞歸 DFS + hashmap

思路:

Example:
          1
        /    \
       0 ---  2 --
              |   |
               ---

(1)隨著DFS遍歷src_Graph,對每一個(gè)結(jié)點(diǎn)src_node,clone一個(gè)cloned_node,
然后對src_node的src_node_neighbor結(jié)點(diǎn)們遞歸重復(fù)相同的clone過程 并將cloned_node_neighbors link到cloned_node中。
(2)在遍歷的過程中,為避免重復(fù)clone,將已經(jīng)cloned的結(jié)點(diǎn)保存到hashmap中, src_node -> cloned_node,
這樣一來在遍歷中對于src_node若在map中已經(jīng)存在,則map.get(src_node)即get出已經(jīng)clone過的cloned_node,直接link(避免新建再clone)。
(3)依照題意,Nodes are labeled uniquely,所以此題map其實(shí)可以是src_node_label -> cloned_node_label,
但為了滿足若不同nodes的label相同的情況,這里map是src_node -> cloned_node
(4)另外,遍歷方式也可以是BFS,利用queue實(shí)現(xiàn),其他過程不變。

Time Complexity: O(N) Space Complexity: O(N)

Solution2:stack DFS + hashmap

思路一致,用stack使得訪問順序不同,深度優(yōu)先

Solution3:queue BFS + hashmap (not finished)

思路一致,用queue使得訪問順序不同,廣度優(yōu)先

Solution1 Code:

public class Solution {
    private HashMap<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap<UndirectedGraphNode, UndirectedGraphNode>();

    public UndirectedGraphNode cloneGraph(UndirectedGraphNode src_node) {
        return clone(src_node);
    }

    private UndirectedGraphNode clone (UndirectedGraphNode src_node) {
        if(src_node == null)
            return null;

        if(map.containsKey(src_node))
            return map.get(src_node);

        //clone clone_node from src_node
        UndirectedGraphNode cloned_node = new UndirectedGraphNode(src_node.label);
        map.put(src_node, cloned_node);
        for(UndirectedGraphNode src_node_neighbor: src_node.neighbors) {
            cloned_node.neighbors.add(clone(src_node_neighbor));
        }
        return cloned_node;
    }
}

Solution2 Code:

public class Solution {
    public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
        if (node == null) return null;
        HashMap<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap();    // src_node -> cloned_node
        Stack<UndirectedGraphNode> stack = new Stack<UndirectedGraphNode>();   // for DfS
        
        // first node
        UndirectedGraphNode first_cloned_node = new UndirectedGraphNode(node.label);
        map.put(node, first_cloned_node); //add first node to HashMap
        
        stack.push(node);        
        while (!stack.isEmpty()) { 
            UndirectedGraphNode src_node = stack.pop();
            UndirectedGraphNode cloned_node = map.get(src_node);
            for(UndirectedGraphNode neighbor : src_node.neighbors) {
                UndirectedGraphNode cloned_neighbor;
                if(map.containsKey(neighbor)) {
                    // already visited
                    cloned_neighbor = map.get(neighbor);
                }
                else {
                    // first time visit
                    cloned_neighbor = new UndirectedGraphNode(neighbor.label);
                    map.put(neighbor, cloned_neighbor);
                    stack.push(neighbor);
                }
                cloned_node.neighbors.add(cloned_neighbor);
            }
        }
        return first_cloned_node;
    }
}

Solution3 Code:

public class Solution {
    public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
        if (node == null) return null;
        HashMap<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap();    // src_node -> cloned_node
        Queue<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>();   // for BfS
        
        // first node
        UndirectedGraphNode first_cloned_node = new UndirectedGraphNode(node.label);
        map.put(node, first_cloned_node); //add first node to HashMap
        
        queue.offer(node);        
        while (!queue.isEmpty()) { 
            UndirectedGraphNode src_node = queue.poll();
            UndirectedGraphNode cloned_node = map.get(src_node);
            for(UndirectedGraphNode neighbor : src_node.neighbors) {
                UndirectedGraphNode cloned_neighbor;
                if(map.containsKey(neighbor)) {
                    // already visited
                    cloned_neighbor = map.get(neighbor);
                }
                else {
                    // first time visit
                    cloned_neighbor = new UndirectedGraphNode(neighbor.label);
                    map.put(neighbor, cloned_neighbor);
                    queue.add(neighbor);
                }
                cloned_node.neighbors.add(cloned_neighbor);
            }
        }
        return first_cloned_node;
    }
}

Tag_Round1 Code:

public class Solution {
    public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
        if(node == null) return null;
        
        Map<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap<>();
        UndirectedGraphNode copy_node = new UndirectedGraphNode(node.label);
        map.put(node, copy_node);
        
        dfs_clone(node, map);
        
        return copy_node;
    }
    
    private void dfs_clone(UndirectedGraphNode node, Map<UndirectedGraphNode, UndirectedGraphNode> map) {
        
        UndirectedGraphNode copy_node = map.get(node);
        for(int i = 0; i < node.neighbors.size(); i++) {
            UndirectedGraphNode next = node.neighbors.get(i);
            if(!map.containsKey(next)) { // unvisited
                UndirectedGraphNode copy_next = new UndirectedGraphNode(next.label);
                map.put(next, copy_next);
                dfs_clone(next, map);
            }
            UndirectedGraphNode copy_next = map.get(next);
            copy_node.neighbors.add(copy_next);   
        
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容