[leetcode 6] copy-list-with-random-pointer

本文探讨了如何对带有随机指针的链表进行深拷贝,提供了两种方法:一是通过创建节点映射进行拷贝,二是直接在原链表中插入拷贝节点再分离。分析了代码实现细节及效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述
现在有一个这样的链表:链表的每一个节点都附加了一个随机指针,随机指针可能指向链表中的任意一个节点或者指向空。
请对这个链表进行深拷贝。
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.

思路

  • 为原链表每个结点编号,并创建一个 <RandomListNode *, int> 的map的key-value对作为目录;
  • 按照编号个数创建新链表,并为新链表创建一个<int,RandomListNode *> 的查找目录;
  • 遍历原链表完成深拷贝。

最先按照这个思路做时新链表没有用new的方式创建而是直接创建结点对象,导致函数运行完后局部变量在栈中被释放,答案出错。 后来改用new在堆内存申请空间,运行成功。
运行时间:25 ms,占用内存:1772K

代码

/**
 * 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;
        RandomListNode *node = head;
        map<RandomListNode *, int> mp1;
        int index = 0;
        while (node) // 给原链表编号
        {
            mp1[node] = index;
            index++;
            node = node->next;
        }
        map<int, RandomListNode *> mp2;
        while ((--index) >= 0) // 创建新链表并编号
        {
            RandomListNode *ptr = new RandomListNode(0);
            mp2[index] = ptr;
        }
        for (node = head; node != NULL; node = node->next) // 遍历并完成深拷贝
        {
            mp2[mp1[node]]->label = node->label;
            mp2[mp1[node]]->next = node->next == NULL ? NULL : mp2[mp1[node->next]];
            mp2[mp1[node]]->random = node->random == NULL ? NULL : mp2[mp1[node->random]];
        }
        return mp2[0];
    }
};

大佬们的代码:
按照惯例做完后拿出零食欣赏大佬们的代码。
思路:

  • 遍历原链表,为每一个结点拷贝一个新结点,插入到原结点的后面;
  • 再次遍历链表,为每一个拷贝结点分配随即指针;
  • 分离链表。

代码:

/**
 * 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;
        RandomListNode *copy, *node;
        for (node = head; node != NULL; node = copy->next)
        {
            copy = new RandomListNode(node->label);
            copy->next = node->next;
            node->next = copy;
        }
        for (node = head; node != NULL; node = copy->next)
        {
            copy = node->next;
            copy->random = node->random == NULL ? NULL : node->random->next;
        }
        for (node = head, copy = head->next, head = head->next; node != NULL; )
        {
            node->next = copy->next;
            node = node->next;
            copy->next = node == NULL ? NULL : node->next;
            copy = node == NULL ? NULL : node->next;
        }
        return head;
    }
};

运行时间:17 ms,占用内存:1376K
学习了~

PS:感谢DXX送的老鼠抱枕~~爱你❤

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值