复制带随机指针的链表

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

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

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

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

 

 

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/
class Solution {
public:
    Node* copyRandomList(Node* head) {
        if(head == NULL){
            return head;
        }
        
        Node *p = head;
        Node *q = NULL;
        while(p != NULL){
            q = new Node(p->val);
            q->random = p->random;
            q->next = p->next;
            p->next = q;
            p = q->next;
        }
        
        Node *copyList = head->next;
        p = head;
        q = head->next;
        
        while(q->next != NULL){
            if(q->random != NULL){
                q->random = q->random->next;
            }
            else{
                q->random = NULL;
            }
            q = q->next->next;
        }
        if(q->random != NULL){
            q->random = q->random->next;
        }

        q = head->next;
        while(q->next != NULL){
            p->next = q->next;
            p = p->next;
            q->next = p->next;
            
            q = q->next;
        }
        p->next = q->next;
        
        return copyList;
    }
};

解题思路:

1.遍历一遍预原链表,在每个原结点后创建一个其拷贝结点,如:A -> A' -> B -> B' -> ······ -> X -> X' -> NULL

2.再从头遍历一遍链表处理random。注意,给random赋值的时候要注意对空指针的判断。

3.再从头遍历一遍链表处理next,将原列表与拷贝列表解开。注意:原列表最后一个结点要指向NULL。

4.返回拷贝链表。

 

时间复杂度=O(3n)=O(n), 空间复杂度=O(1).

posted @ 2020-03-12 23:35  jenningszheng  阅读(249)  评论(0编辑  收藏  举报