LEETCODE刷题-138.随机链表的复制

一,题目

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

构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 

例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。

返回复制链表的头节点。

用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

  • val:一个表示 Node.val 的整数。
  • random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为  null 。

你的代码  接受原链表的头节点 head 作为传入参数。

示例 1:

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

二,解题思路

创建一个哈希表,两次遍历链表。

  1. 创建哈希映射:使用 unordered_map hmap 来存储原链表节点和新链表节点之间的映射关系。

  2. 复制每个节点的值:第一个 while 循环遍历原链表,为每个节点创建一个新的节点,并将其插入到 hmap 中。新节点的值与原节点的值相同,nextrandom 指针初始化为 nullptr

    cpp

    Node *p = head;
    while (p) {
        hmap.insert({p, new Node(p->val)});
        p = p->next;
    }
  3. 复制 nextrandom 指针:第二个 while 循环再次遍历原链表,使用 hmap 来设置新节点的 nextrandom 指针。对于每个节点,新节点的 next 指针指向原节点 next 所指向的新节点,新节点的 random 指针指向原节点 random 所指向的新节点。

    cpp

    p = head;
    while (p) {
        hmap[p]->next = hmap[p->next];
        hmap[p]->random = hmap[p->random];
        p = p->next;
    }
  4. 返回新链表的头节点:最后,函数返回新链表的头节点,即 hmap[head]

    cpp

    return hmap[head];

这个函数的关键在于使用 unordered_map 来存储原节点和新节点之间的映射关系,这样在复制 nextrandom 指针时可以轻松地引用对应的新节点。

请注意,这段代码假设 Node 结构体定义如下:

cpp复制

struct Node {
    int val;
    Node *next;
    Node *random;
    Node(int x) : val(x), next(nullptr), random(nullptr) {}
};

这个 Node 结构体包含一个整数值 val,两个指针 nextrandom,以及一个构造函数来初始化节点。在实际应用中,你需要确保适当地管理内存,避免内存泄漏。

三,代码实现

class Solution {
public:
    Node* copyRandomList(Node* head) {
        unordered_map<Node*, Node*> hmap;
        Node* p = head;
        while(p)
        {
            hmap.insert({p, new Node(p->val)});
            p = p->next;
        }

        p = head;
        while(p)
        {
            hmap[p]->next = hmap[p->next];
            hmap[p]->random = hmap[p->random];
            p = p->next;
        }
        return hmap[head];
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值