首页 > 其他分享 >OJ随机链表的复制题目分析

OJ随机链表的复制题目分析

时间:2025-01-05 12:31:33浏览次数:3  
标签:Node 题目 OJ struct next 链表 copy cur

题目内容:

138. 随机链表的复制 - 力扣(LeetCode)

分析: 

这道题目,第一眼感觉非常乱,这是正常的,但是我们经过仔细分析示例明白后,其实也并不是那么难。现在让我们一起来分析分析吧!

1.题目要求的是链表的复制,那么我们得想我们该怎么做,才能很好地进行下去呢?

2.是直接把原链表一个一个地移动过来?这思路果断不对,它还要保持原来的链表不被复制啊.

3.经过观察,我们发现13的random指向7。各种穿插的,所以我们采用

 

//复制
     struct Node* cur=head;
    while(cur)
    {
      
        
        struct Node* copy=(struct Node*)malloc(sizeof(struct Node));
        copy->val=cur->val;
         struct Node*Next=cur->next;
        cur->next=copy;
        copy->next=Next;
        cur=Next;

    }

复制部分:

先在每个数复制下来,分别放在它的原数字的下一个。即下图:

4.接着你看它原链表的那些数字。7的random指向NULL,13的random指向7.(其他的省略说)。7的next指向13。看到这种规律,我们试想是不是可以把复制的也弄成这样子,就形成了一个独立的复制链表了,对吧? 

连线部分:

 

 //连接线
   cur=head;
    while(cur)
    {
        struct Node* copy=cur->next;
       // struct Node* Next=cur->next->next;
        if(cur->random==NULL)
        {
            copy->random=NULL;
        }
        else
        {
            copy->random=cur->random->next;

        }
        cur=cur->next->next;
        
    }

如下图:

你看复制完了之后,是不是可以直接它复制那部分挪下来,它也是不会破坏原链表的,这是不是就符合题目要求了对吧?

5.完成了这步了之后,到了我们一个一个挪的那部分了。

如下图:

 

解释上图:

 //复制的挪下来,恢复原链表
    
    
    
    struct Node* copyhead=NULL,*copytail=NULL;
    cur=head; 
    while(cur)
    {
        struct Node* copy=cur->next;
        struct Node* Next=copy->next; 
        //尾插
        if(copyhead==NULL)
        {
            copyhead=copytail=copy;
        }
        else
        {
            copytail->next=copy;
            copytail=copytail->next;
            
        }

挪动部分:

当我们复制完了之后,开始挪新的复制链表:

1.首先定义一个cur指针指向head头。再定义一个next指针指向cur的下一个(方便它随时都能返回找到copy的位置)。

2.定义两个指针分别为copyhead和copytail指针,放在新的链表那里当作移动工具和最后返回工具

2.接着,相当于进行尾插,当 第一次时,copyhead和copytail都为空时,就把copy值直接放到这个指针

3.不为空时,就把copy值放到copytail的下一位。

恢复部分:

最后,恢复原来的链表,即去掉它copy的那些数:

1.因为我们上面都没有动过cur的位置,所以这里就直接使用cur这个指针就行了。

2.把cur的下一个给Next即:  把cur的下一个next给给cur的next的next(即cur的下下个)。

  //恢复链表
            cur->next=Next;
            cur=Next; 

总代码: 

/**
 * Definition for a Node.
 * struct Node {
 *     int val;
 *     struct Node *next;
 *     struct Node *random;
 * };
 */

struct Node* copyRandomList(struct Node* head) {
	//复制
     struct Node* cur=head;
    while(cur)
    {
      
        
        struct Node* copy=(struct Node*)malloc(sizeof(struct Node));
        copy->val=cur->val;
         struct Node*Next=cur->next;
        cur->next=copy;
        copy->next=Next;
        cur=Next;

    }
    //连接线
   cur=head;
    while(cur)
    {
        struct Node* copy=cur->next;
       // struct Node* Next=cur->next->next;
        if(cur->random==NULL)
        {
            copy->random=NULL;
        }
        else
        {
            copy->random=cur->random->next;

        }
        cur=cur->next->next;
        
    }
    //复制的挪下来,恢复原链表
    
    
    
    struct Node* copyhead=NULL,*copytail=NULL;
    cur=head; 
    while(cur)
    {
        struct Node* copy=cur->next;
        struct Node* Next=copy->next; 
        //尾插
        if(copyhead==NULL)
        {
            copyhead=copytail=copy;
        }
        else
        {
            copytail->next=copy;
            copytail=copytail->next;
            
        }
        //恢复链表
            cur->next=Next;
            cur=Next; 
    
    }
    return copyhead;
}

最后,特别要注意的是:cur的位置要每到一部分都要及时更新变成head。(因为它每一部分都在改变),不然就会像我一开始那样,发现怎么都不正确哇哇哇哇。

每次鸡汤:

好啦,到了我们的每次鸡汤部分:

虽然我每次迈出的那一步都很小,但是终究会有那么一天会到达终点的。加油吧,青年。

标签:Node,题目,OJ,struct,next,链表,copy,cur
From: https://blog.csdn.net/go_bai/article/details/144916916

相关文章

  • [数据结构学习笔记4] 链表
    链表(LinkedLists)和数组类似,链表也是用来存放一组数据。和数组不一样的是,链表存储不需要连续的内存位置,一个链表由很多节点组成,节点与节点间通过一个next指针关联。图示:NodeValue/DataNext 链表操作:查找一个值:通过链表的next指针一直往下跳直到:1.找到了想......
  • 物联网工程技术毕业设计题目万能选题方法模板(源码+原理图+PCB+洞洞板+开题报告+任务书
    万功题目模板**如:**1、把物联网技术改成STM32单片机,就成了《基于STM32的智能交通信号控制系统设计》2、把物联网改成89C51单片机,就成了《基于89C51的智能交通信号控制系统设计》3、把物联网改成ESP32单片机,就成了《基于ESP32的智能交通信号控制系统设计》以此类推下面本......
  • 160链表相交
    哈希肯定是能解的,就想着有没有其他方法。最开始的思路是翻转链表,然后再来找相交结点,但是题目要求不能改链表结构。官方题解的第二种方法确实巧妙,如果有相交结点的话最多通过两次遍历就一定能找到,因此。在分析中,其实我们也可以把两个不相交的链表看做相交,但是相交结点为nullptr代......
  • 《约瑟夫问题 循环链表》
    约瑟夫问题循环链表题解来了!!!#include<bits/stdc++.h>usingnamespacestd;intm,n;structNode{ intdata; Node*next;}*head,*p,*tail,*temp;intmain(){ cin>>m>>n; head=newNode; head->next=NULL; tail=head; for(inti=1;i&......
  • 19删除链表的倒数第n个结点
    正常思路,先遍历一遍链表得到长度,然后进行第二次遍历得到待删除结点的上一个结点classSolution{public:ListNode*removeNthFromEnd(ListNode*head,intn){ListNode*dummyHead=newListNode(0);dummyHead->next=head;ListNode*cur=......
  • 小程序毕业设计最新题目大全,1000 道小程序毕业设计推荐
    博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w+、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌......
  • 24. 两两交换链表中的节点(中)
    目录题目法一、迭代法二、递归题目给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。法一、迭代varswapPairs=function(head){letdummy={next:head}letp1=dummywhil......
  • MyBatis 核心知识点详解:题目与解析
    MyBatis核心知识点详解:题目与解析MyBatis是一个强大的持久层框架,广泛应用于Java开发中。本文将结合具体的题目,详细解析MyBatis的核心知识点,包括事务控制、自增主键回填、参数获取、结果映射以及动态SQL,帮助大家更好地掌握这些内容。题目1:MyBatis控制事务关于MyBatis......
  • 力扣刷题:栈和队列OJ篇(下)
    大家好,这里是小编的博客频道小编的博客:就爱学编程很高兴在CSDN这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!!目录1.括号匹配问题(1)题目描述(2)解题思路2.循环队列(1)题目描述(2)解题思路快乐的时光总是短暂,咱们下篇博文再见啦!!!如果小编的文章会对......
  • 24 两两交换链表中的节点
    思路简单,但是操作的时候还是要注意细节,特别是某些结点的next指针变化需要格外关注,报了很多次错。因为没注意到:每次替换两个结点后,应该让当前的后面的结点指向下两个结点的靠后一点的结点。主要还是画完图后没有走一遍链表classSolution{public:ListNode*swapPairs(List......