题目:
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.
本题与前面的链表结构都不太一样,其每个节点都有next和random两个指针,题目要求对该链表进行深度拷贝,也就是说必须返回一个与原链表完全相同的链表,而且不能有原链表重复。难点在于random指针的复现,因为如果我们单纯的将链表的next实现之后,会发现random指针并无法准确的找到而变得十分困难。所以我们可以先使用hash表来存储要浮现的节点,然后在给其next和random指针赋值,代码入下:
public RandomListNode copyRandomList1(RandomListNode head){
HashMap<RandomListNode, RandomListNode> map = new HashMap<>();
RandomListNode cur = head;
while(cur!= null){
map.put(cur, new RandomListNode(cur.label));
cur = cur.next;
}
cur = head;
while(cur != null){
map.get(cur).next = map.get(cur.next);
map.get(cur).random = map.get(cur.random);
cur = cur.next;
}
return map.get(head);
}
另外一种方法比较巧妙,主要分为以下三步:
- 1,在原始链表每个元素的后面复制一个新的节点等于前面的节点,相当于插入操作
- 2,赋值random指针,新创建的节点的random指针要指向对应新创建的指针
- 3,将该链表重新分成两个,一个是原始指针,一个是返回的结果
代码如下所示:
public RandomListNode copyRandomList(RandomListNode head) {
if(head == null)
return head;
RandomListNode cur = head;
while(cur != null){
RandomListNode sec = new RandomListNode(cur.label);
sec.next = cur.next;
cur.next = sec;
cur = cur.next.next;
}
cur = head;
while(cur != null){
if(cur.random != null)
cur.next.random = cur.random.next;
cur = cur.next.next;
}
cur = head;
RandomListNode res = head.next;
RandomListNode sec = res;
while(sec.next != null){
cur.next = cur.next.next;
cur = cur.next;
sec.next = sec.next.next;
sec = sec.next;
}
cur.next = cur.next.next;
return res;
}
可以结合这个示意图进行理解: