Leetcode 138 - Copy List with Random Pointer(链表复制)

链接

https://leetcode.com/problems/copy-list-with-random-pointer/#/description

题意

一个链表,有三个属性:int lableRandomListNode* nextRandomListNode* random,其中random可能指向该链表中的任意一个节点或者空结点,要求复制该链表

思路

我们用L表示原来的链表,L1表示复制后的链表
用x代表L中的节点,x’代表L1中的节点

思路1

最容易想到的思路就是先将链表的next复制完后,再去复制random。但是比如如下情况:
original
此时L的1的random指向n,当L1复制random指针的时候,如果需要定位到其的n’节点,需要 O(n) 的时间,那么时间复杂度最坏会上升到: O(n2

思路2

为了优化时间复杂度,我们需要做的就是:对于L1,如何快速定位到某个节点的random指针指向的节点?
如上图:我们知道1->random = n,那么需要得到1'->random = n'。我们可以建立一个nn'映射,即用unorder_map<RandomListNode, RandomListNode>来建立L到L1的节点的一一对应。
如下图所示:
map
这样,时间复杂度为 O(n) ,空间复杂度为 O(n)

思路3

空间复杂度能否继续优化?
既然我们不能用unordered_map,观察上面的图:我们的unordered_map就是为了建立映射,如1映射到1’,为什么不能直接用1指向1’呢?我们这样来建立链表:
2
这样,我们获得1’的random指针时,只需要通过:1->next->random = 1->random->next
最后再将两个链表拆开即可。

细节

注意random指向NULL节点

代码

思路3的代码

/**
 * 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* p = head;
        while (p) {
            RandomListNode* next_node = p->next;
            p->next = new RandomListNode(p->label);
            p->next->next = next_node;
            p = next_node;
        }
        p = head;
        while (p) {
            p->next->random = p->random ? p->random->next : NULL;
            p = p->next->next;
        }
        RandomListNode *cphead = head->next;
        p = head;
        while (p) {
            RandomListNode* q = p->next;
            p->next = p->next->next;
            q->next = q->next ? q->next->next : NULL;
            p = p->next;
        }
        return cphead;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值