zoukankan      html  css  js  c++  java
  • 138. Copy List with Random Pointer

    • Total Accepted: 98004
    • Total Submissions: 368319
    • Difficulty: Medium
    • Contributors: Admin

    A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

    Return a deep copy of the list.

    分析


    本题实际上就是有向图的深拷贝。

    方法一

    时间复杂度O(3N)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    /**
     * Definition for singly-linked list with a random pointer.
     * struct RandomRandomListNode {
     *     int label;
     *     RandomRandomListNode *next, *random;
     *     RandomRandomListNode(int x) : label(x), next(NULL), random(NULL) {}
     * };
     */
    class Solution {
    public:
        RandomListNode *copyRandomList(RandomListNode *head) {
            if(head == NULL) return NULL;
             
            RandomListNode* p = head;
            //copy every node and link to one's next position
            while(p != NULL){
                RandomListNode* next = p->next;
                RandomListNode* newNode = new RandomListNode(p->label);
                p->next = newNode;
                newNode->next = next;
                p = next;
            }
             
            //every new node's random link to orignal link's next node
            p = head;
            while(p != NULL){
               if(p->random != NULL)p->next->random = p->random->next;
               p = p->next->next;
            }
             
            //split the list
            RandomListNode dummy1(0), dummy2(0);
            RandomListNode* p1 = &dummy1, * p2 = &dummy2;
            p = head;
            while(p != NULL){
                p1->next = p; 
                p1 = p1->next;
                p2->next = p->next; 
                p2 = p2->next;
                p = p->next->next;
                if(p == NULL){
                    p1->next = NULL;
                    p2->next = NULL;
                }
            }
            head = dummy1.next;
            return dummy2.next;
        }
    };

    方法二

    使用map去做,建立 新旧节点的 key-value 对,然后拷贝连接关系即可
    (用C++写会runtime error, Java就没问题,不懂)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    /**
     * Definition for singly-linked list with a random pointer.
     * struct RandomListNode {
     *     int label;
     *     RandomListNode *next, *random;
     *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
     * };
     */
    class Solution {
    public:
        RandomListNode *copyRandomList(RandomListNode *head) {
            if(head == NULL) return NULL;
             
            unordered_map<RandomListNode*, RandomListNode*> map;
            RandomListNode* p = head;
            while(p != NULL){
                map.insert({p,new RandomListNode(p->label)});
                p = p->next;
            }
             
            for(auto p: map){
                RandomListNode *newNode = (p.second);
                newNode->next = map[p.first->next];
                newNode->random = map[p.first->random];
            }
            return map[head];
        }
    };

    方法三

    使用迭代,原理和方法二一样
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Solution {
    public:
        unordered_map<RandomListNode*, RandomListNode*>mp;
        RandomListNode *copyRandomList(RandomListNode *head) 
        {
            if(!head) return NULL;
            if(mp[head]!=NULL) return mp[head];
            mp[head] = new RandomListNode(head->label);
            mp[head] -> next = copyRandomList(head->next);
            mp[head] -> random = copyRandomList(head->random);
            return mp[head];
        }
    };




  • 相关阅读:
    洛谷P2640 神秘磁石(欧拉筛法)
    并查集
    高精度算法
    手写堆
    对拍的使用
    unity4.6学习Ugui中文文档-------参考-UGUI Rect Transform
    使用c#访问脚本里变量的方法
    Unity3d 脚本相互调用
    set_union的几个例子[转]
    C++ 关键字——friend
  • 原文地址:https://www.cnblogs.com/zhxshseu/p/7e1a5d4e0d37364386891201ebb9b68a.html
Copyright © 2011-2022 走看看