LeetCode 138. Copy List with Random Pointer

14 篇文章 0 订阅
2 篇文章 0 订阅

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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值