【LeeCode】每日一题:复制带随机指针的链表

简介: 【LeeCode】每日一题:复制带随机指针的链表

👻内容专栏:《LeetCode刷题专栏》

🐨本文概括: 138.复制带随机指针的链表

🐼本文作者:花 碟

🐸发布时间:2023.5.18

复制带随机指针的链表

力扣链接-> 138.复制带随机指针的链表

题目描述:

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

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

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

返回复制链表的头节点。

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

val:一个表示 Node.val 的整数。

random_index:随机指针指向的节点索引(范围从 0n-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]]

示例2:

输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]

示例3:

输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]

思想:

思想:

如下图中,节点1的random指向节点3,节点3的random指向节点2,节点2的random指向空

我们可以把此题列出三个步骤来解决:

1.将每个复制节点插入到每个原节点的后面,如下图:

在遍历原链表的每个节点的同时,往后插入复制节点。为了避免原链表头节点的修改,将head给到cur,让cur迭代往后走,每次走都需要新开辟一块copy的空间,cur->val也要给到copy->val

2.设置复制节点的随机指针random

这是最核心的要点,观察上方图片:原链表中节点1的random指向了原链表节点3,复制节点1的random指向了原链表节点3的next,相同的,原链表中节点3的random指向了原链表节点2,复制节点3的random指向了原链表节点2的next,所以我们有结论,原链表节点irandom指向了原链表节点j(j存在),那么复制节点irandom会指向原链表节点jnext

3.分离复制节点进行尾插为一个新的链表,同时还原原链表,如下图:

代码实现:

/**
 * Definition for a Node.
 * struct Node {
 *     int val;
 *     struct Node *next;
 *     struct Node *random;
 * };
 */
struct Node* copyRandomList(struct Node* head) {
    struct Node* cur = head;
    //1.每个拷贝节点插入到每个原节点的后面  
    while(cur)
    {
        struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
        copy->val = cur->val;
        //插入copy节点
        struct Node* next = cur->next;
        cur->next = copy;
        copy->next = next;
        //迭代往后走
        cur = next;
    }
    //2.设置复制节点的随机指针random
    cur = head;
    while(cur)
    {
        struct Node* copy = cur->next;
        if(cur->random == NULL)
        {
            copy->random = NULL;
        }else
        {
            copy->random = cur->random->next;
        }
        //迭代往后走
        cur = copy->next;
    }
    //3.分离复制节点为一个新的链表进行尾插并还原链表
    struct Node* copyHead = NULL,*copyTail = NULL;
    cur = head;
    while(cur)
    {
        struct Node* copy = cur->next;
        struct Node* next = copy->next;
        if(copyTail == NULL)
        {
            copyHead = copyTail = copy;
        }else
        {
            copyTail->next = copy;
            copyTail = copy;
        }
        //还原链表
        cur->next = next;
        cur = next;
    }
    return copyHead;
}
目录
相关文章
|
3天前
|
算法
LeetCode刷题---21.合并两个有序链表(双指针)
LeetCode刷题---21.合并两个有序链表(双指针)
|
3天前
|
算法
LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)
LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)
|
3天前
教你三指针拿捏链表翻转
教你三指针拿捏链表翻转
|
3天前
数据结构--链表刷题(一)快慢指针(下)
数据结构--链表刷题(一)快慢指针
15 0
|
3天前
数据结构--链表刷题(一)快慢指针(上)
数据结构--链表刷题(一)快慢指针
16 0
|
3天前
|
算法 C语言 索引
环形链表(快慢指针)
环形链表(快慢指针)
|
3天前
|
存储 编译器 C语言
【数据结构】深入浅出理解链表中二级指针的应用
【数据结构】深入浅出理解链表中二级指针的应用
32 0
|
3天前
|
算法 Java
快慢指针该如何操作?本文带你认识快慢指针常见的三种用法及在链表中的实战
快慢指针该如何操作?本文带你认识快慢指针常见的三种用法及在链表中的实战
29 0
|
3天前
|
存储 算法
LeetCode刷题--- 61. 旋转链表(快慢指针+闭合为环)
LeetCode刷题--- 61. 旋转链表(快慢指针+闭合为环)
|
3天前
|
算法 索引
LeetCode刷题--- 138. 复制带随机指针的链表(哈希表+迭代)
LeetCode刷题--- 138. 复制带随机指针的链表(哈希表+迭代)