模拟
- 第一趟遍历,在结点的右侧复制映射。
- 第二趟遍历,复制 r a n d o m random random。
- 第三趟遍历,将链表中的映射结点取出作为新链表。

 初始链表如图①。
有必要说明,原结点如 
    
     
      
       
        1
       
      
      
       1
      
     
    1~
    
     
      
       
        5
       
      
      
       5
      
     
    5 ,映射结点就是 
    
     
      
       
        1
       
       
        ‘
       
      
      
       1`
      
     
    1‘~
    
     
      
       
        5
       
       
        ‘
       
      
      
       5`
      
     
    5‘。
 复制映射的结果是,原结点的 
    
     
      
       
        n
       
       
        e
       
       
        x
       
       
        t
       
      
      
       next
      
     
    next 指向映射结点,如图②。
有了映射链表后, r a n d o m random random 和 n e x t next next 的关系请看图②, 2 − 4 2-4 2−4 , 2 ‘ − 4 ‘ 2`-4` 2‘−4‘ 的 r a n d o m random random 指向自己理解。(理解了,请看代码)
我们的映射结点经过被映射,复制 r a n d o m random random 这两步后,已经形成结点的深拷贝,现在需要把结点按顺序取出 (看图看代码) 。
至此三次遍历生成随机结点链表的深拷贝。请读者多加思考,复写代码吧~
class Solution {
public:
    Node* copyRandomList(Node* head) {
        for(auto p = head;p;p=p->next->next) { //在结点右侧复制映射。
            auto q = new Node(p->val);
            q->next = p->next;
            p->next = q;
        }
        for(auto p = head;p;p=p->next->next) //复制 random
            if(p->random) p->next->random = p->random->next;
        auto dummy = new Node(-1) , cur = dummy;
        for(auto p = head;p;p = p->next){ //断链
            cur = cur->next = p->next;
            p->next = p->next->next;
        }
        return dummy->next;
    }
};
- 时间复杂度 : O ( n ) O(n) O(n) ,三趟遍历的时间复杂度 O ( n ) O(n) O(n)。
- 空间复杂度 : O ( 1 ) O(1) O(1) ,只使用常数级空间 。
AC




















