复杂链表的复制(剑指Offer-35)
题面
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
示例
示例 1:
1输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
2输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
示例 2:
1输入:head = [[1,1],[2,1]]
2输出:[[1,1],[2,1]]
示例 3:
1输入:head = [[3,null],[3,0],[3,null]]
2输出:[[3,null],[3,0],[3,null]]
示例 4:
1输入:head = []
2输出:[]
3解释:给定的链表为空(空指针),因此返回 null。
限制
1 -10000 <= Node.val <= 10000
2 Node.random 为空(null)或指向链表中的节点。
3 节点数目不超过 1000 。
思路
复制各节点,构建拼接链表: 设原链表为
node1 → node2 → ⋯
,构建的拼接链表如下所示:node1 → node1new → node2 → node2new → ⋯
构建新链表各节点的 random 指向: 当访问原节点 cur 的随机指向节点 cur.random 时,对应新节点 cur.next 的随机指向节点为 cur.random.next 。
拆分原 / 新链表: 设置 pre / cur 分别指向原 / 新链表头节点,遍历执行 pre.next = pre.next.next 和 cur.next = cur.next.next 将两链表拆分开。
返回新链表的头节点 res 即可。
代码
1/*
2// Definition for a Node.
3class Node {
4public:
5 int val;
6 Node* next;
7 Node* random;
8
9 Node(int _val) {
10 val = _val;
11 next = NULL;
12 random = NULL;
13 }
14};
15*/
16class Solution {
17public:
18 Node* copyRandomList(Node* head) {
19 if(head == nullptr) return nullptr;
20 Node *cur = head;
21
22 while(cur != nullptr){
23 Node *t = new Node(cur->val);
24 t->next = cur->next;
25 cur->next = t;
26 cur = t->next;
27 }
28
29 cur = head;
30 while(cur != nullptr){
31 if(cur->random != nullptr)
32 cur->next->random = cur->random->next;
33 cur = cur->next->next;
34 }
35
36 cur = head->next;
37 Node *pre = head, *res = head->next;
38 while(cur->next != nullptr){
39 pre->next = pre->next->next;
40 cur->next = cur->next->next;
41 pre = pre->next;
42 cur = cur->next;
43 }
44 pre->next = nullptr;
45 return res;
46 }
47};