题目地址:
https://www.lintcode.com/problem/copy-list-with-random-pointer/description
给定一个链表,每个节点有两个指针域,分别指向下一个节点和另一个随机的节点,这个随机节点可以是自己可以是别的节点也可能是null。要求深拷贝这个链表,返回拷贝后的链表头。
法1:DFS。用一个哈希表,key记录已经copy好原链表的节点,value记录深拷贝出来的节点。接着开始对原链表进行DFS,如果遇到没copy过的节点,就将其copy,然后分别去copy其next和random,最后将新copy的节点返回;如果当前节点已经copy过,则直接返回其value。代码如下:
import java.util.HashMap;
import java.util.Map;
public class Solution {
/**
* @param head: The head of linked list with a random pointer.
* @return: A new head of a deep copy of the list.
*/
public RandomListNode copyRandomList(RandomListNode head) {
// write your code here
Map<RandomListNode, RandomListNode> map = new HashMap<>();
// 记null为已经copy好,其对应的节点就是null
map.put(null, null);
return copy(head, map);
}
private RandomListNode copy(RandomListNode head, Map<RandomListNode, RandomListNode> map) {
// 如果head已经被copy过,则返回其对应的value
if (map.containsKey(head)) {
return map.get(head);
}
// 否则说明当前head没copy过,将其copy并建立映射关系
map.put(head, new RandomListNode(head.label));
// 递归地copy其next和random接上去
map.get(head).next = copy(head.next, map);
map.get(head).random = copy(head.random, map);
// 最后按照定义返回head对应的节点
return map.get(head);
}
}
class RandomListNode {
int label;
RandomListNode next, random;
RandomListNode(int x) {
this.label = x;
}
}
时空复杂度 O ( n ) O(n) O(n)。
法2:BFS。也是开一个哈希表,作用与上面相同。同时做BFS,开一个队列,每次都将队列中取出的节点的next和random拷贝好(如果之前已经拷贝过,那么就直接从map中取出来),然后接在后面。代码如下:
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
public class Solution5 {
/**
* @param head: The head of linked list with a random pointer.
* @return: A new head of a deep copy of the list.
*/
public RandomListNode copyRandomList(RandomListNode head) {
// write your code here
if (head == null) {
return null;
}
Map<RandomListNode, RandomListNode> map = new HashMap<>();
map.put(null, null);
map.put(head, new RandomListNode(head.label));
Queue<RandomListNode> queue = new LinkedList<>();
queue.offer(head);
while (!queue.isEmpty()) {
RandomListNode x = queue.poll();
if (!map.containsKey(x.next)) {
map.put(x.next, new RandomListNode(x.next.label));
queue.offer(x.next);
}
map.get(x).next = map.get(x.next);
if (!map.containsKey(x.random)) {
map.put(x.random, new RandomListNode(x.random.label));
queue.offer(x.random);
}
map.get(x).random = map.get(x.random);
}
return map.get(head);
}
}
时空复杂度 O ( n ) O(n) O(n)。