138. 复制带随机指针的链表

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

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

题目的意思:

题目的意思指的是拷贝后的新链表上每一个结点的随机指针也应该指向和原链表位置对应的结点

也就是说,我们在拷贝链表的时候,新链表上的每一个结点的随机指着都应该指向新链表上位置和旧链表对应的结点

思路:

是无法通过一次性就建好链表的,比如说在建第一个结点的时候,第一个的结点的随机指针指向第4个结点,由于我们第4个结点还没创建,所以不可能一次性就把所有随机指针都初始化好

所以,深度拷贝链表,至少需要二次操作:

我们可以先建一次链表,不初始化随机指针,只初始化结点的值

然后再遍历一遍链表,把随机指针补充好

通过分析发现,如果通过从头到尾遍历去找要随机指针,效率肯定是非常慢的,比如说第一个结点的随机指针指向第99个结点,我们则需要从第一个结点不断next才可以找到第99个结点,所以这种从头到尾遍历找随机指针的方法非常慢,不可行

所以我们可以用一个Map,存原结点到新结点的一一对应关系,原链表第一个结点的映射就是新链表的第一个结点,原链表第二个结点的映射就是新链表的第二个结点,以此类推

那么我们在找随机指针的时候,就可以变快很多,比如说第一个结点的随机指针指向第99个结点,那么我们直接找原链表的第一个结点的随机指针,然后映射出对应的指针,就找到了

效率:98.22%

code:

/**
 * 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)
            return NULL;
        RandomListNode * ret = new RandomListNode(head -> label);
        RandomListNode *cope_ret_head = ret, *temp_head = head;
        map<RandomListNode*,RandomListNode*> m;
        m[temp_head] = ret;
        while (temp_head = temp_head -> next) {
            RandomListNode * t = new RandomListNode(temp_head -> label);
            ret -> next = t;
            ret = ret -> next;
            m[temp_head] = ret;
        }
        temp_head = head;
        ret = cope_ret_head;
        while (temp_head) {
            ret -> random = m[temp_head -> random];
            temp_head = temp_head -> next;
            ret = ret -> next;
        }
        return cope_ret_head;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值