【数据结构】一题带你出师链表!

简介: 【数据结构】一题带你出师链表!

题目链接

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


题目描述

给你一个长度为 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. 逐一拷贝链表结点并将其链接在原结点的后面(操作图示如下)
  2. 拷贝结点的random:把原结点后面的拷贝结点的random和原结点random的后一个结点拷贝起来(操作图示如下) 按照这个思路,将所有的拷贝结点的random连接起来:
  3. 将拷贝结点摘下尾插到新链表中,同时恢复原链表(操作图示如下) 逐一将拷贝结点尾插到新链表的同时恢复原链表的链接关系,最后返回newhead即可

解题代码

综上,该题完整解题代码如下:

struct Node* BuyNode(int x)
{
  struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));
  if (newnode == NULL)
  {
    perror("malloc fail::");
    return NULL;
  }
  newnode->val = x;
  newnode->next = NULL;
    newnode->random=NULL;
  return newnode;
}
 
struct Node* copyRandomList(struct Node* head)
{
    //1.逐一拷贝链表结点并将其链接在原结点的后面
 
    struct Node*cur=head;
    while(cur)
    {
        int data=cur->val;
        struct Node*new=BuyNode(data);
        new->next=cur->next;
        cur->next=new;
        cur=cur->next->next;
    }
 
    //2.拷贝结点的random,把原结点后面的拷贝结点的random和原结点random的后一个结点拷贝起来.
   
    cur=head;
    while(cur)
    {
        if(cur->random!=NULL)
        {
             cur->next->random=cur->random->next;
        }
        else
        {
             cur->next->random=cur->random;
        }
        cur=cur->next->next;
    }
 
    //3.将拷贝结点摘下尾插到新链表中,同时恢复原链表.
 
    cur=head;
    struct Node*newhead=NULL;
    struct Node*tail=newhead;//记录新表尾
    while(cur)
    {
        //先把新结点给新链表
        if(newhead==NULL)
        {
            newhead=cur->next;
            tail=newhead;
        }
        else
        {
            tail->next=cur->next;
            tail=tail->next;
        }
 
        //再改变老节点的关系
        cur->next=tail->next;
        cur=cur->next;
    }
 
    if(tail!=NULL)//防止空指针解引用
    {
        tail->next=NULL;
    }
    
    return newhead;
 
}

提交运行:


结语

这是一道经典的链表面试题目,其中不仅仅是考察我们对题目的思路,同样也需要我们有很扎实的链表插入,删除,链接等操作的基本功.如果可以很轻松的完成这道题,那么恭喜你,你的链表已经达到了可以出师的水平,请继续向着星辰大海进发吧!

希望这篇对Leetcode:138.随机链表的复制题目详解能对大家有所帮助,欢迎大佬们留言或私信与我交流.

学海漫浩浩,我亦苦作舟!关注我,大家一起学习,一起进步!




相关文章
|
4天前
|
存储
数据结构链表详解(不仅顺序表可以,我链表也可以)
数据结构链表详解(不仅顺序表可以,我链表也可以)
12 0
|
6天前
|
存储
数据结构第二课 -----线性表之单向链表
数据结构第二课 -----线性表之单向链表
|
6天前
|
存储 算法 Java
数据结构与算法 数组和链表
数据结构与算法 数组和链表
12 0
|
6天前
|
存储 Java
深入浅出数据结构之链表
深入浅出数据结构之链表
|
6天前
|
C++
数据结构(双链表
数据结构(双链表
11 1
|
6天前
|
存储 缓存
[数据结构]~双向+循环链表从(0~1)
[数据结构]~双向+循环链表从(0~1)
|
6天前
|
存储
数据结构第三课 -----线性表之双向链表
数据结构第三课 -----线性表之双向链表
|
6天前
|
存储 Java
数据结构奇妙旅程之顺序表和链表
数据结构奇妙旅程之顺序表和链表
|
6天前
|
存储 C语言
数据结构基础:双链表结构、实现
数据结构基础:双链表结构、实现
|
6天前
|
存储
数据结构基础:一篇文章教你单链表(头插,尾插,查找,头删等的解析和代码)
数据结构基础:一篇文章教你单链表(头插,尾插,查找,头删等的解析和代码)