【链表】复杂链表的复制

题目:

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

解答:

 

 

 3 
 4 /*
 5 *解题思路:
 6 *1、遍历链表,复制每个结点,如复制结点A得到A1,将结点A1插到结点A后面;
 7 *2、重新遍历链表,复制老结点的随机指针给新结点,如A1.random = A.random.next;
 8 *3、拆分链表,将链表拆分为原链表和复制后的链表
 9 */
10 public class Solution {
11     public RandomListNode Clone(RandomListNode pHead) {
12         if(pHead == null) {
13             return null;
14         }
15          
16         RandomListNode currentNode = pHead;
17         //1、复制每个结点,如复制结点A得到A1,将结点A1插到结点A后面;
18         while(currentNode != null){
19             RandomListNode cloneNode = new RandomListNode(currentNode.label);
20             RandomListNode nextNode = currentNode.next;
21             currentNode.next = cloneNode;
22             cloneNode.next = nextNode;
23             currentNode = nextNode;
24         }
25          
26         currentNode = pHead;
27         //2、重新遍历链表,复制老结点的随机指针给新结点,如A1.random = A.random.next;
28         while(currentNode != null) {
29             currentNode.next.random = currentNode.random==null?null:currentNode.random.next;
30             currentNode = currentNode.next.next;
31         }
32          
33         //3、拆分链表,将链表拆分为原链表和复制后的链表
34         currentNode = pHead;
35         RandomListNode pCloneHead = pHead.next;
36         while(currentNode != null) {
37             RandomListNode cloneNode = currentNode.next;
38             currentNode.next = cloneNode.next;
39             cloneNode.next = cloneNode.next==null?null:cloneNode.next.next;
40             currentNode = currentNode.next;
41         }
42          
43         return pCloneHead;
44     }
45 }

 

C++版本:

/*
// 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 (NULL == head) 
        {
            return head;
        }
        
        // 1. 在旧链表中创建新链表, 此时不处理新链表的兄弟结点
        Node *curr = head;
        while (curr != NULL)
        {
            // Node *clonenode = new Node(curr->val);
            // Node *nextnode = curr->next;
            // curr->next = clonenode;
            // clonenode->next = nextnode;
            // curr = nextnode;
            Node * clonenode = new Node(curr->val);
            clonenode->next = curr->next;
            curr->next = clonenode;
            curr = clonenode->next;
        }
        
        
        // 2. 根据旧链表的兄弟结点, 初始化新链表的兄弟结点
        // 重新遍历链表, 复制老结点的随机指针给新结点
        curr = head;
        while (curr != NULL)
        {
            // curr->random == NULL 时, 不能直接赋值为curr->random->next,所以需要判断下
            curr->next->random = (curr->random == NULL ? NULL : curr->random->next);
            curr = curr->next->next;
        }
        
        // 3. 拆分链表, 将链表拆分为源链表和复制后的链表
        curr = head;
        Node *clonehead = head->next;
        
        while (curr != NULL)
        {
            Node *clonenode = curr->next;
            
            curr->next = clonenode->next;
            curr = curr->next;
            
            // clonenode->next = (clonenode->next == NULL ? NULL : clonenode->next->next);
            clonenode->next = (curr == NULL ? NULL : curr->next);
        }
        
        return clonehead;        
    }
};

 

posted @ 2020-05-06 17:23  梦醒潇湘  阅读(177)  评论(0)    收藏  举报