LeetCode刷题笔记-图

97 阅读1分钟

133 Clone Graph Medium

考察对图的遍历和利用HashMap拷贝的方法。

图的遍历就是两个经典的方法:DFS和BFS。

BFS经常用Queue实现,DFS经常用递归实现(可改为栈实现)。

拷贝方法是用HashMap,key存原始值,value存copy的值,用DFS,BFS方法遍历帮助拷贝neighbors的值。

  1. DFS 递归

    Input: A graph G and a root v of G
    procedure DFS(G,v):
       label v as discovered
       for all edges from v to w in G.adjacentEdges(v) do
           if vertex w is not labeled as discovered then
               recursively call DFS(G,w)
    
    /**
    * 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;
           }        
           Map<UndirectedGraphNode, UndirectedGraphNode> hashmap = new HashMap<>();
    
           UndirectedGraphNode copy = new UndirectedGraphNode(node.label);
           hashmap.put(node,copy);
           DFS(hashmap, node);     //递归
           return copy;
       }
    
       private void DFS(Map<UndirectedGraphNode, UndirectedGraphNode> hashmap, UndirectedGraphNode node) {
           if(node == null) {
               return;
           }
           for(UndirectedGraphNode neighbor:node.neighbors) {
               if(!hashmap.containsKey(neighbor)) {
                   UndirectedGraphNode copyNeighbor = new UndirectedGraphNode(neighbor.label);
                   hashmap.put(neighbor, copyNeighbor);
                   DFS(hashmap, neighbor);
               }
               hashmap.get(node).neighbors.add(hashmap.get(neighbor));
           }
       }
    }
    
  2. DFS 非递归

    Input: A graph G and a root v of G
    procedure DFS-iterative(G,v):
       let S be a stack
       label v as discovered
       S.push(v)
       while S is not empty
           v ← S.pop() 
           if v is not labeled as discovered:
               label v as discovered
               for all edges from v to w in G.adjacentEdges(v) do
                   S.push(w)
    
    /**
    * 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;
           }
           Deque<UndirectedGraphNode> stack = new ArrayDeque<>();
           Map<UndirectedGraphNode, UndirectedGraphNode> hashmap = new HashMap<>();
    
           UndirectedGraphNode copy = new UndirectedGraphNode(node.label);
           hashmap.put(node,copy);
           stack.addFirst(node);
           while(!stack.isEmpty()) {
               UndirectedGraphNode v = stack.removeFirst();
               for(UndirectedGraphNode neighbor:v.neighbors) {
                   if(!hashmap.containsKey(neighbor)) {
                       UndirectedGraphNode copyNeighbor = new UndirectedGraphNode(neighbor.label);
                       hashmap.put(neighbor, copyNeighbor);
                       stack.addFirst(neighbor);
                   }  
                   hashmap.get(v).neighbors.add(hashmap.get(neighbor));
               }        
           }
           return copy;
       }
    }
    
  3. BFS 队列

对于一个节点来说先把所有neighbors都检查一遍,再从第一个neighbor开始,循环往复。 BFS可以帮助寻找最短路径。

Input: A graph G and a root v of G
procedure BFS(G,v) is
   create a queue Q
   label v as discovered
   enqueue v onto Q
   while Q is not empty
       v ← Q.dequeue()
       for all edges from v to w in G.adjacentEdges(v) do
           if vertex w is not labeled as discovered then
               label w as discovered
               enqueue w onto Q
/**
* 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;
       }
       LinkedList<UndirectedGraphNode> queue = new LinkedList<>();
       Map<UndirectedGraphNode, UndirectedGraphNode> hashmap = new HashMap<>();

       UndirectedGraphNode copy = new UndirectedGraphNode(node.label);
       hashmap.put(node,copy);
       queue.add(node);
       while(!queue.isEmpty()) {
           UndirectedGraphNode v = queue.remove();
           for(UndirectedGraphNode neighbor:v.neighbors) {
               if(!hashmap.containsKey(neighbor)) {
                   UndirectedGraphNode copyNeighbor = new UndirectedGraphNode(neighbor.label);
                   hashmap.put(neighbor, copyNeighbor);
                   queue.add(neighbor);
               }  
               hashmap.get(v).neighbors.add(hashmap.get(neighbor));
           }        
       }
       return copy;
   }
}