【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;
}
目录
相关文章
|
1月前
链表指针的传参,传值和传地址
本文讨论了链表操作中指针传参的问题,特别是指针的传值与传地址的区别,并提供了修正代码,以确保链表插入操作能正确地修改指针指向的地址。
16 1
链表指针的传参,传值和传地址
|
6月前
|
存储 C语言
用指针处理链表
用指针处理链表
59 3
|
1月前
|
存储
一篇文章了解区分指针数组,数组指针,函数指针,链表。
一篇文章了解区分指针数组,数组指针,函数指针,链表。
18 0
|
1月前
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
22 0
|
4月前
【数据结构OJ题】复制带随机指针的链表
力扣题目——复制带随机指针的链表
51 1
【数据结构OJ题】复制带随机指针的链表
|
3月前
|
Python
【Leetcode刷题Python】138. 复制带随机指针的链表
LeetCode上题目“138. 复制带随机指针的链表”的Python解决方案,包括两种方法:一种是在每个节点后复制一个新节点然后再分离出来形成新链表;另一种是构建一个字典来跟踪原始节点与其副本之间的映射关系,从而处理新链表的构建。
20 1
|
3月前
|
存储 算法 数据处理
指针与链表
指针与链表
65 0
|
5月前
|
算法
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
|
6月前
|
存储 C语言
链表—初始化指针变和创建新的节点------区别应用分析
链表—初始化指针变和创建新的节点------区别应用分析
|
6月前
|
存储 缓存 搜索推荐
指针链表
指针链表
43 0