LeetCode 138. Copy List with Random Pointer

来源:互联网 发布:java勇敢的心游戏 编辑:程序博客网 时间:2024/06/06 09:35

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.

本题出现了一个新的链表结点结构,结点有两个指针域,一个指向下一个结点,一个指向链表中的随机结点或者NULL。要求对该链表进行深复制(就是 copy 出来的副本与原本是完全独立,互不影响。改动原来的,不会影响副本,反之亦然。)

有两种解法

第一种解法:
按照原链表next的顺序依次创建结点、建立next关系,同时把原结点与新结点的一一对应关系保存到一个hash_map中。然后根据这个hash_map,在第二次循环时建立random关系。这种方法的时间复杂度是O(n),空间复杂度也是O(n)。
当然也可以用一次迭代完成,每次循环既建立next关系又建立random关系。 若果random 指向的结点在副本链表中还未创建,则创建并建立random关系;否则,直接连接副本结点的random关系。

class Solution {public:    RandomListNode *copyRandomList(RandomListNode *head) {        std::unordered_map<RandomListNode*, RandomListNode*> map;        RandomListNode preHead(0);        for (RandomListNode *next = &preHead; head; next = next->next, head = head->next) {            if (map[head] == NULL) {                RandomListNode* node = new RandomListNode(head->label);                map[head] = node;            }            next->next = map[head];            if (head->random && map[head->random] == NULL) {                RandomListNode* node = new RandomListNode(head->random->label);                map[head->random] = node;            }            map[head]->random = map[head->random];        }        return preHead.next;    }};

第二种解法:
三次迭代。原链表:1-2-3-4-5
第一次迭代,按照原链表next的顺序依次创建结点并插入到原结点之后。以此替代hash_map建立原结点、新结点之间的对应关系。即链表变为:1-1'-2-2'-3-3'-4-4'-5-5'
第二次迭代,建立random关系。cp 为副本结点,org 为原结点,那么有以下关系:cp->random = org->rndom->next>
第三次迭代,将链表拆分成两个。
这种方法的时间复杂度是O(n),(额外的空间复杂度是O(1))空间复杂度是O(n)。

class Solution {public:    RandomListNode *copyRandomList(RandomListNode *head) {        if (!head) return NULL;        RandomListNode *cur = head;        while (cur)        {            RandomListNode *cp = new RandomListNode(cur->label);            cp->next = cur->next;            cur->next = cp;            cur = cur->next->next;        }        cur = head;        while (cur)        {            if (cur->random)            {                cur->next->random = cur->random->next;            }            cur = cur->next->next;        }        cur = head;        RandomListNode *next, *copy;        RandomListNode *copyHead = cur->next;        while (cur)        {            next = cur->next->next;            copy = cur->next;            cur->next = next;            if (next)            {                copy->next = next->next;            }            else            {                copy->next = NULL;            }            cur = cur->next;        }        return copyHead;    }};