【你会这道经典的链表面试题吗】

简介: 【你会这道经典的链表面试题吗】

只有启程,才会达到理想和目的地

e9f42c42b15d49cc9f7139dea8c088c7.jpg

---》题目跳转

题目描述:

给你一个长度为 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 作为传入参数。

示例:

0a12512466ec46a5ab5451a0cd6196c6.png

解题思路:

常规思路就是遍历链表,记住当前结点random的相对位置,然后malloc结点,一个一个链接起来,在通过相对位置找到自身的random,这样的思路时间复杂度是多少呢?

很明显这是典型的O(N^2),那么还有更好的思路吗?

第一步:复制原节点并且将复制的结点链接在原节点之后;

第二步:找到复制结点的random;

第三步:恢复链表。

听起来好像挺简单的,但是这个题整体考查了我们对链表增删查改的 拿捏度,每一步大家最好先是把图画好,然后有了大致思路再去撸代码,这样的效果会更加高效一些。

这里有个动图大家可以参考下:

b43435507d4c450a8653fd074ba3cc63.gif

具体代码:

struct Node* copyRandomList(struct Node* head) {
  //1 复制结点链接在原结点之后
    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;
    }
    //2 链接随机指针
    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 恢复链表,尾插数据
    cur=head;
    struct Node* newHead=NULL,*newTail=NULL;
    while(cur)
    {
        struct Node* copy=cur->next;
        struct Node* next=copy->next;
        cur->next=next;
        if(newHead==NULL)
            newHead=newTail=copy;
        else
        {
            newTail->next=copy;
            newTail=newTail->next;
        }
        cur=next;
    }
    return newHead;
}

每一步大家代码实现可能不一样,但是总体思路应该是差不多的,这道链表题能够很好的考察大家对链表的掌握情况,大家也快去试试吧!

目录
相关文章
|
6月前
面试题 02.04:分割链表
面试题 02.04:分割链表
54 0
|
6月前
|
存储 算法 索引
链表面试题
链表面试题
链表面试题
|
6月前
【一刷《剑指Offer》】面试题 17:合并两个排序的链表
【一刷《剑指Offer》】面试题 17:合并两个排序的链表
|
6月前
【一刷《剑指Offer》】面试题 16:反转链表
【一刷《剑指Offer》】面试题 16:反转链表
|
6月前
【一刷《剑指Offer》】面试题 15:链表中倒数第 k 个结点
【一刷《剑指Offer》】面试题 15:链表中倒数第 k 个结点
|
6月前
|
机器学习/深度学习
【一刷《剑指Offer》】面试题 13:在 O(1) 时间删除链表结点
【一刷《剑指Offer》】面试题 13:在 O(1) 时间删除链表结点
|
6月前
【一刷《剑指Offer》】面试题 5:从尾到头打印链表
【一刷《剑指Offer》】面试题 5:从尾到头打印链表
|
6月前
|
算法 搜索推荐 索引
数据结构与算法⑥(第二章OJ题,下)后八道链表面试题(下)
数据结构与算法⑥(第二章OJ题,下)后八道链表面试题
46 0
|
6月前
|
算法 程序员 索引
数据结构与算法⑥(第二章OJ题,下)后八道链表面试题(中)
数据结构与算法⑥(第二章OJ题,下)后八道链表面试题
41 0
|
6月前
|
算法 C语言 C++
数据结构与算法⑥(第二章OJ题,下)后八道链表面试题(上)
数据结构与算法⑥(第二章OJ题,下)后八道链表面试题
32 0