133克隆图 · Clone Graph
[抄题]:
克隆一张无向图,图中的每个节点包含一个 label
和一个列表 neighbors
。
[思维问题]:
[一句话思路]:
先BFS克隆点(一个点+扩展所有邻居),再克隆邻居(一个点+扩展所有邻居)。
[输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):
[画图]:
[一刷]:
- bfs的结果应该存在一个节点构成的数组中ArrayList<UndirectedGraphNode>,作为for(UndirectedGraphNode n: nodes)循环的已有上限,表示对点的统计
- 最后返回的是mapping.get(headnode);表示新克隆出来的图,不用新定义一个result,因为返回的不是数组
[二刷]:
- 先取node, 再取出每个node的多个neighbor
- copy都只是循环,不是函数,不是没调用呢嘛
- node第一次既要进入queue,也要进入检查的set
- bfs中返回一个新new出来的ArrayList<UndirectedGraphNode>
- corner case返回的是null,想想就知道
[三刷]:
- bfs中,对每一个节点的每一个neighbor都要操作。因此必须循环套循环
- 二级循环中是对临时变量进行操作的,即 for (UndirectedGraphNode neighbor : head.neighbors)中的neighbor
[四刷]:
[五刷]:
[总结]:
- DFS要有栈,可能会stackoverflow,所以尽量用BFS。
- 为保证代码风格良好,特殊情况缩进放短的内容,一般情况不缩进放长的内容。 eg 特殊情况+{continue;} 而一般情况+{长语句;}
[复杂度]:Time complexity: O(边数+点数) Space complexity: O(n)
[英文数据结构或算法,为什么不用别的数据结构或算法]:
- 图和树的区别:从A到B有多条路径
- Queue的实现(右边)有:linkedlist arraylist pq, 实现之后才有offer等方法
- for (UndirectedGraphNode n : manynodes) ,前者是临时变量,后者是数组名,表示遍历。右边是范围上限
[其他解法]:
[Follow Up]:
- 无权图的最短路:哈希表distance(起点,到起点的距离)
- 克隆linkedlist, tree
[LC给出的题目变变变]:
138. Copy List with Random Pointer:也是先复制节点,再复制指针
public class Solution { /* * @param node: A undirected graph node * @return: A undirected graph node */ public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { //HashMap HashMap<UndirectedGraphNode,UndirectedGraphNode> mapping = new HashMap<>(); //corner case if (node == null) { return null; } //bfs ArrayList<UndirectedGraphNode> manynodes = bfs(node); //copy node for (UndirectedGraphNode n : manynodes) { mapping.put(n,new UndirectedGraphNode(n.label)); } //copy neighbor for (UndirectedGraphNode n : manynodes) { UndirectedGraphNode newNode = mapping.get(n); for (UndirectedGraphNode neighbor : n.neighbors) { UndirectedGraphNode newNeighbor = mapping.get(neighbor); newNode.neighbors.add(newNeighbor); } } //return return mapping.get(node); } //bfs private ArrayList<UndirectedGraphNode> bfs(UndirectedGraphNode node) { Queue<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>(); HashSet<UndirectedGraphNode> set = new HashSet<>(); queue.offer(node); set.add(node); while (!queue.isEmpty()) { UndirectedGraphNode head = queue.poll(); for (UndirectedGraphNode neighbor : head.neighbors) { if (!set.contains(neighbor)) { queue.offer(neighbor); set.add(neighbor); } } } return new ArrayList<UndirectedGraphNode>(set); } }