本篇给出几道关于图的问题。但是没有深度搜索和广度搜索的题型,仅是与图结构相关的。
Clone Graph
这道题为深度克隆一张图。我们分点和点的对应关系分别进行克隆。
public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
if (node == null) {
return node;
}
// use bfs algorithm to traverse the graph and get all nodes.
ArrayList<UndirectedGraphNode> nodes = getNodes(node);
// copy nodes, store the old->new mapping information in a hash map
HashMap<UndirectedGraphNode, UndirectedGraphNode> mapping = new HashMap<>();
for (UndirectedGraphNode n : nodes) {
mapping.put(n, new UndirectedGraphNode(n.label));
}
// copy neighbors(edges)
for (UndirectedGraphNode n : nodes) {
UndirectedGraphNode newNode = mapping.get(n);
for (UndirectedGraphNode neighbor : n.neighbors) {
UndirectedGraphNode newNeighbor = mapping.get(neighbor);
newNode.neighbors.add(newNeighbor);
}
}
return mapping.get(node);
}
private ArrayList<UndirectedGraphNode> getNodes(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)){
set.add(neighbor);
queue.offer(neighbor);
}
}
}
return new ArrayList<UndirectedGraphNode>(set);
}
Copy List with Random Pointer
这道题是深度克隆一个链表,链表上的节点带随机指针。与上道题相似,先克隆节点再克隆关系。
public RandomListNode copyRandomList(RandomListNode head) {
if (head == null) {
return null;
}
HashMap<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
RandomListNode dummy = new RandomListNode(0);
RandomListNode pre = dummy, newNode;
while (head != null) {
if (map.containsKey(head)) {
newNode = map.get(head);
} else {
newNode = new RandomListNode(head.label);
map.put(head, newNode);
}
pre.next = newNode;
if (head.random != null) {
if (map.containsKey(head.random)) {
newNode.random = map.get(head.random);
} else {
newNode.random = new RandomListNode(head.random.label);
map.put(head.random, newNode.random);
}
}
pre = newNode;
head = head.next;
}
return dummy.next;
}
Topological Sorting
这道题是有序图的拓扑排序的标准算法,理解拓扑排序即可理解下面代码的过程。
public ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph) {
// write your code here
ArrayList<DirectedGraphNode> result = new ArrayList<DirectedGraphNode>();
HashMap<DirectedGraphNode, Integer> map = new HashMap();
for (DirectedGraphNode node : graph) {
for (DirectedGraphNode neighbor : node.neighbors) {
if (map.containsKey(neighbor)) {
map.put(neighbor, map.get(neighbor) + 1);
} else {
map.put(neighbor, 1);
}
}
}
Queue<DirectedGraphNode> q = new LinkedList<DirectedGraphNode>();
for (DirectedGraphNode node : graph) {
if (!map.containsKey(node)) {
q.offer(node);
result.add(node);
}
}
while (!q.isEmpty()) {
DirectedGraphNode node = q.poll();
for (DirectedGraphNode n : node.neighbors) {
map.put(n, map.get(n) - 1);
if (map.get(n) == 0) {
result.add(n);
q.offer(n);
}
}
}
return result;
}