剑指Offer:复杂链表的复制(35)

题目描述:

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

解答思路:

遍历原来的链表并拷贝每一个节点,将拷贝的节点放到之前节点的后面,新的链表是新旧节点交替的(A->A'->B->B'->C->C');

像这样:

然后迭代这个链表,让新结点跟旧结点随机指针指向相同

就像下面这个图一样:

最后从第一个开始解除链表以返回原始链表和克隆链表。

最后得到这样:

 1 public class Solution {
 2   public Node copyRandomList(Node head) {
 3 
 4     if (head == null) {
 5       return null;
 6     }
 7 
 8     Node ptr = head;
 9     while (ptr != null) {
10 
11       // 克隆结点
12       Node newNode = new Node(ptr.val);
13 
14       // 将克隆的结点放到原结点旁边
15       newNode.next = ptr.next;
16       ptr.next = newNode;
17       ptr = newNode.next;
18     }
19 
20     ptr = head;
21 
22     //迭代让新结点的随机指针指向跟旧结点相同
23     while (ptr != null) {
24       ptr.next.random = (ptr.random != null) ? ptr.random.next : null;
25       ptr = ptr.next.next;
26     }
27 
28     //解除链表,返回原始链表和克隆的链表。
29     Node ptr_old_list = head; // A->B->C
30     Node ptr_new_list = head.next; // A'->B'->C'
31     Node head_old = head.next;
32     while (ptr_old_list != null) {
33       ptr_old_list.next = ptr_old_list.next.next;
34       ptr_new_list.next = (ptr_new_list.next != null) ? ptr_new_list.next.next : null;
35       ptr_old_list = ptr_old_list.next;
36       ptr_new_list = ptr_new_list.next;
37     }
38     return head_old;
39   }
40 }

 

posted @ 2020-09-05 21:41  手下留情  阅读(125)  评论(0编辑  收藏  举报