【Leetcode】拿捏链表(五)——138. 复制带随机指针的链表

简介: 【Leetcode】拿捏链表(五)——138. 复制带随机指针的链表

作者:一个喜欢猫咪的的程序员

专栏:《Leetcode》

喜欢的话:世间因为少年的挺身而出,而更加瑰丽。                                  ——《人民日报》

目录

138. 复制带随机指针的链表


138. 复制带随机指针的链表


138. 复制带随机指针的链表

https://leetcode.cn/problems/copy-list-with-random-pointer/


题目描述:


示例:

示例 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]]


思路:


题目的要求:

使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。

本题我们分为三步完成:


  • 我们先将要复制的链表copy,先不管random我们先将val和next复制好。将cur和next来复制整个链表并将其链接在对应的数的后面。

fd100519cb3640d388e5b8f554e1e97d.gif

  • 链接完成后,我们开始处理random,我们链接后的链表是这样的。


当cur->random的下一个刚好是copy要链接的位置。因此当cur->random不为空时,copy->random=cur->random->next;cur->random为空时,置空就好了

当random处理完后,我们要将这两个链表拆开,并且保证两个链表要跟一开始一样、cur->next-next将链表变为原来的连接形式。我们用newhead来记录新链表的起始位置,copyTail来遍历链表将一个链表拆成两个链表。

时间复杂度:O(N)            空间复杂度:O(1)              

                     

代码实现:

struct Node* copyRandomList(struct Node* head) {
  struct Node*cur=head;
    while(cur)
    {
        struct Node*next=cur->next;
        struct Node*copy=(struct Node*)malloc(sizeof(struct Node));
        copy->val=cur->val;
        cur->next=copy;
        copy->next=next;
        cur=next;
    }
    cur=head;
    while(cur)
    {
        struct Node*copy=cur->next;
        if(cur->random)
        {
            copy->random=cur->random->next;
        }
        else
        {
            copy->random=NULL;
        }
        cur=copy->next;
    }
    cur=head;
    struct Node*copyTail=NULL;
    struct Node*newhead=NULL;
    while(cur)
    {
        struct Node*copy=cur->next;
        struct Node*next=copy->next;
        cur->next=next;
        if(copyTail==NULL)
        {
            newhead=copyTail=copy;
        }
        else
        {
            copyTail->next=copy;
            copyTail=copyTail->next;
        }
        cur=next;
    }
    return newhead;
}
相关文章
|
1月前
【力扣】-- 移除链表元素
【力扣】-- 移除链表元素
35 1
|
1月前
Leetcode第21题(合并两个有序链表)
这篇文章介绍了如何使用非递归和递归方法解决LeetCode第21题,即合并两个有序链表的问题。
48 0
Leetcode第21题(合并两个有序链表)
|
1月前
LeetCode第二十四题(两两交换链表中的节点)
这篇文章介绍了LeetCode第24题的解法,即如何通过使用三个指针(preNode, curNode, curNextNode)来两两交换链表中的节点,并提供了详细的代码实现。
18 0
LeetCode第二十四题(两两交换链表中的节点)
|
1月前
Leetcode第十九题(删除链表的倒数第N个节点)
LeetCode第19题要求删除链表的倒数第N个节点,可以通过快慢指针法在一次遍历中实现。
43 0
Leetcode第十九题(删除链表的倒数第N个节点)
|
1月前
|
索引
力扣(LeetCode)数据结构练习题(3)------链表
力扣(LeetCode)数据结构练习题(3)------链表
78 0
|
1月前
|
存储
一篇文章了解区分指针数组,数组指针,函数指针,链表。
一篇文章了解区分指针数组,数组指针,函数指针,链表。
18 0
|
1月前
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
24 0
|
1月前
【LeetCode 10】142. 环形链表 II
【LeetCode 10】142. 环形链表 II
21 0
|
5月前
|
存储 SQL 算法
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
|
5月前
|
存储 SQL 算法
LeetCode 题目 86:分隔链表
LeetCode 题目 86:分隔链表