Graph 133. Clone Graph in three ways(bfs, dfs, bfs(recursive))

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
         / \
         \_/

Basically just clone the graph like clone a list in leetcode 138.

there are three ways t solve this (just traverse the graph and put new node into map)

/**
 * Definition for undirected graph.
 * class UndirectedGraphNode {
 *     int label;
 *     List<UndirectedGraphNode> neighbors;
 *     UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
 * };
 */
public class Solution {
    //dfs
    Map<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap<UndirectedGraphNode, UndirectedGraphNode>();
    public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
        if(node==null) return null;
        //copy graph(deep copy), hashmap
        map.put(node, new UndirectedGraphNode(node.label));
        helper(node);
        return map.get(node);
    }
    void helper(UndirectedGraphNode node){
        for(int i = 0; i< node.neighbors.size(); i++){
            UndirectedGraphNode neighbor = node.neighbors.get(i);
            if(!map.containsKey(neighbor)){// not visited
                UndirectedGraphNode newNode = new UndirectedGraphNode(neighbor.label);
                map.put(neighbor, newNode);//visited
                helper(neighbor);//why put helper here: where put stack where to recursive(update 1)
            }
            map.get(node).neighbors.add(map.get(neighbor)); //set the link of neighbors
        }
    }
}

Solution 2: bfs queue

/**
 * Definition for undirected graph.
 * class UndirectedGraphNode {
 *     int label;
 *     List<UndirectedGraphNode> neighbors;
 *     UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
 * };
 */
public class Solution {
    public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
        if(node==null) return null;
        //bfs
        LinkedList<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>();
        queue.offer(node);
        Map<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap<UndirectedGraphNode, UndirectedGraphNode>();
        
        UndirectedGraphNode newNode = new UndirectedGraphNode(node.label);
        map.put(node,newNode);
        while(!queue.isEmpty()){
            UndirectedGraphNode cur = queue.poll();//pop
            for(int i = 0; i<cur.neighbors.size(); i++){
                UndirectedGraphNode neighbor = cur.neighbors.get(i);
                if(!map.containsKey(neighbor)){
                    queue.offer(neighbor);
                    newNode = new UndirectedGraphNode(neighbor.label);
                    map.put(neighbor, newNode);
                    map.get(cur).neighbors.add(newNode);
                }
                //if contains the key
                else map.get(cur).neighbors.add(map.get(neighbor));
            }
        }
        return map.get(node);
    }
}

Solution 3: dfs with all node connected.

/**
 * Definition for undirected graph.
 * class UndirectedGraphNode {
 *     int label;
 *     List<UndirectedGraphNode> neighbors;
 *     UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
 * };
 */
public class Solution {
    public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
        if(node == null) return null;
        //dfs, if not visited, visited it and set it to visited, stack
        LinkedList<UndirectedGraphNode> stack = new LinkedList<>();//add first
        stack.push(node);
        Map<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap<>();
        UndirectedGraphNode newNode = new UndirectedGraphNode(node.label);
        map.put(node, newNode);
        while(!stack.isEmpty()){
            UndirectedGraphNode cur = stack.pop();//pop
            for(int i = 0; i<cur.neighbors.size(); i++){
                UndirectedGraphNode neighbor = cur.neighbors.get(i);//neighbor of current 
                if(!map.containsKey(neighbor)){//put neighbor into hashmap (visited)
                    newNode = new UndirectedGraphNode(neighbor.label);//copy neighbors
                    map.put(neighbor, newNode);
                    stack.push(neighbor);
                }
                //set the link of neighbors
                map.get(cur).neighbors.add(map.get(neighbor));
                
            }
            
        }
        return map.get(node);
    }
}
// relationship in hashmap
// key,             value
// cur,             map.get(cur)
// cur.neighbors,   newNode/ map.get(eighbor)

What if nodes are not connnected partly: just write a loop to chekc all the node(call dfs for each node) in the graph

https://www.geeksforgeeks.org/depth-first-search-or-dfs-for-a-graph/

 

How do you represent the graph(one way from leetcode, another from geekforgeek)

Lastly: think about the time complexity of them

posted @ 2018-08-17 12:40  wz30  阅读(492)  评论(0编辑  收藏  举报