LeetCode 138 复制带随机指针的链表

链接:https://leetcode-cn.com/problems/copy-list-with-random-pointer

 

给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。

要求返回这个链表的 深拷贝。 

我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

val:一个表示 Node.val 的整数。
random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为  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 。

 

这道题画个图会比较好理解,做法就是在原链表中,在每个结点的后面复制一个与它相同的结点。然后,让复制的结点的random指针和被复制的结点的一样。再将原链表和复制链表分离开来。

写了两个版本的代码,区别在于一个用的while循环,一个用的for循环,用for循环会比较简洁。还有就是在分离操作的时候,一个用了双指针,有点繁琐,但是很好想啦。其实用一个指针就可以完成分离操作,但要定义一个dummy虚拟头结点。

 

c++代码如下:

 1 class Solution {
 2 public:
 3     Node* copyRandomList(Node* head) {
 4         if(!head) return head;
 5         auto p = head;
 6         while(p){
 7             auto q = new Node(p->val);
 8             q->next = p->next;
 9             p->next = q;
10             p = q->next;
11         }
12         auto k = head;
13         while(k){
14             if(k->random) k->next->random = k->random->next;
15             k = k->next->next;
16         }
17         auto copy = head->next;
18         auto a = head, b = head->next->next; 
19         while(b){
20             a->next->next = b->next;
21             a->next = b;
22             a = b;
23             b = b->next->next;
24         }
25         a->next = b;
26         return copy;
27     }
28 };

更简洁、更妙的解法如下:

 1 class Solution {
 2 public:
 3     Node* copyRandomList(Node* head) {
 4         if(!head) return head;
 5         for(auto p = head; p; p = p->next->next){
 6             auto q = new Node(p->val);
 7             q->next = p->next;
 8             p->next = q;
 9         }
10         
11         for(auto k = head; k; k = k->next->next){
12             if(k->random) k->next->random = k->random->next;
13         }
14         auto dummy = new Node(-1);
15         auto cur = dummy;
16         for(auto p = head; p;p = p->next){
17             cur->next = p->next;
18             p->next = cur->next->next;
19             cur = cur->next;
20         }
21 
22         return dummy->next;
23     }
24 };

 

上一篇:138. 复制带随机指针的链表


下一篇:138-bathPath的作用?