138. Copy List with Random Pointer
题目
原始地址:https://leetcode.com/problems/copy-list-with-random-pointer/#/description
/**
* Definition for singly-linked list with a random pointer.
* class RandomListNode {
* int label;
* RandomListNode next, random;
* RandomListNode(int x) { this.label = x; }
* };
*/
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
}
}
描述
给定一个特殊的链表,每个节点处理包含next指针,还会包含一个random指针,指向该链表中的任意其它节点或者null。要求实现这个链表的深层拷贝。
分析
所谓deep copy就是说我们在完成拷贝后,所有的结构都要拷贝过来,所有的random指针指向原链表中的节点在新链表中对应的节点。
给出两种解法,第一种解法需要需要使用一个哈希表来记录原节点与拷贝后节点的关系,由于第一次遍历并生成拷贝节点时有很多节点还没有完成拷贝,因此只能给拷贝节点的next赋值,同时将新旧节点的对应关系记录到哈希表中,第二次遍历时修改拷贝节点的random值,指向哈希表中原节点对应的拷贝节点即可。
第二种解法不需要分配多余的空间,但需要三次遍历。第一次我们把拷贝生成的新节点都挂到原节点之后,这样不需要哈希表我们也能找到原节点对应的拷贝节点了;第二次遍历的时候把拷贝节点的random值修改为原节点对应的拷贝节点;第三次遍历把链表中的新旧节点分开,恢复原链表的结构并把所有的拷贝节点串起来即可。
解法1
/**
* Definition for singly-linked list with a random pointer.
* class RandomListNode {
* int label;
* RandomListNode next, random;
* RandomListNode(int x) { this.label = x; }
* };
*/
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
if (head == null) {
return head;
}
RandomListNode copyHead = new RandomListNode(0), curr = head, copy = copyHead;
Map<RandomListNode, RandomListNode> map = new HashMap<>();
while (curr != null) {
copy.next = new RandomListNode(curr.label);
copy = copy.next;
copy.random = curr.random;
map.put(curr, copy);
curr = curr.next;
}
curr = copyHead.next;
while (curr != null) {
curr.random = curr.random == null ? null : map.get(curr.random);
curr = curr.next;
}
return copyHead.next;
}
}
解法2
/**
* Definition for singly-linked list with a random pointer.
* class RandomListNode {
* int label;
* RandomListNode next, random;
* RandomListNode(int x) { this.label = x; }
* };
*/
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
if (head == null) {
return null;
}
RandomListNode curr = head, copyHead = new RandomListNode(0), copy;
while (curr != null) {
copy = new RandomListNode(curr.label);
copy.next = curr.next;
curr.next = copy;
curr = copy.next;
}
curr = head;
while (curr != null) {
copy = curr.next;
copy.random = curr.random == null ? null : curr.random.next;
curr = copy.next;
}
curr = head;
copy = copyHead;
while (curr != null) {
copy.next = curr.next;
copy = curr.next;
curr.next = copy.next;
curr = copy.next;
}
return copyHead.next;
}
}