剑指 offer 35. 复杂链表的复制
剑指 Offer 35. 复杂链表的复制
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
示例 1:

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
示例 2:

输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]
示例 3:

输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]
示例 4:
输入:head = []
输出:[]
解释:给定的链表为空(空指针),因此返回 null。
提示:
- -10000 <= Node.val <= 10000
- Node.random 为空(null)或指向链表中的节点。
- 节点数目不超过 1000 。
注意:本题与主站 138 题相同:https://leetcode-cn.com/problems/copy-list-with-random-pointer/
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
Solution 1
1在duplicate()中对节点进行复制,新节点插入到原本节点与原本节点的下一个节点之间。
这样做是为了之后方便对复制后节点的random指向的节点进行定位。
2在changeRandomPtr()中,改变新节点的random指针,其应为原节点的random指向的节点的下一个节点。
3最后拆分链表,把原链表还原并提取出新链表。
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
class Solution {
public Node copyRandomList(Node head) {
duplicate(head);
changeRandomPtr(head);
return split(head);
}
private void duplicate(Node head) {
while (head != null) {
Node node = new Node(head.val);
node.next = head.next;
head.next = node;
head = node.next;
}
}
private void changeRandomPtr(Node head) {
while (head != null) {
Node node = head.next;
if (head.random == null)
node.random = null;
else
node.random = head.random.next;
head = node.next;
}
}
private Node split(Node head) {
if (head == null)
return null;
Node _head_ = head.next;
while (head != null && head.next != null) {
Node node = head.next;
head.next = node.next;
head = node;
}
return _head_;
}
}
Solution 2
cpp
class Solution
{
public:
Node *copyRandomList(Node *head)
{
if (head == NULL)
return NULL;
Node *temp = head, *new_temp = NULL, *new_head = NULL;
while (temp != NULL)
{
new_temp = new Node(temp->val);
new_temp->next = temp->next;
new_temp->random = temp->random;
temp->next = new_temp;
temp = new_temp->next;
}
// traverse and change random
temp = head;
while (temp != NULL)
{
temp = temp->next;
if (temp->random != NULL)
{
temp->random = temp->random->next;
}
temp = temp->next;
}
// split origen and new
new_head = head->next;
temp = head;
new_temp = temp->next;
while (temp != NULL)
{
temp->next = temp->next->next;
temp = temp->next;
if (new_temp->next != NULL)
{
new_temp->next = new_temp->next->next;
new_temp = new_temp->next;
}
}
return new_head;
}
};