题目描述:
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针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 }