C语言每日一题(33)随机链表的复制

力扣138 随机链表的复制

题目描述

给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。

构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 

例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。

返回复制链表的头节点。

思路分析

有很多小伙连题目都读不懂,更别说思路。下面我将进行解释:

其实就是一个关于链表的拷贝,像一般的单链表只需要遍历一遍复制即可,但这个链表多了一个随机指针random,它可以指向链表中的任意一个结点,包括它自己,同时也可以指向空。这时你可能会想到,将链表复制一遍放到新节点,再将random指向对应的源节点的位置不就行了?但题目要求复制链表中的指针都不应指向原链表中的节点 ,这就成了一个大问题。也就是说,如果碰到后面结点的random在它之前,且不知道是是什么位置,单纯的用什么所谓的双指针还是快慢指针都会很麻烦。

基于单链表,这题的最优解是:

将要复制的结点插入到每一个源节点的后面,记为copy,题目要求copy的random不能指回源节点,只能值向复制的结点,会发现,如果要取到对应的复制结点,例如原节点13的random指向7,那复制结点13也要指向复制的7,怎么取到呢,就是原结点13的random的next,是不是很巧妙?基于这个思路,即复制结点的random就是原结点的random的next值。

方法步骤:

1.将需要复制的结点插入到原结点的后面。

2.将复制结点的random指向原结点的random的next值。

3.将链表取下,恢复原链表。

struct Node* copyRandomList(struct Node* head) {
    struct Node* cur=head;//保存头结点,用cur遍历
    while(cur)
    {
        struct Node* copy=(struct Node*)malloc(sizeof(struct Node));//复制结点用malloc创建
        copy->val=cur->val;//
        copy->next=cur->next;//进行插入
        cur->next=copy;
        cur=copy->next;//往下走
    }
    cur=head;//再从头走一遍
    while(cur)//处理random指针
    {
        struct Node* copy=cur->next;
        struct Node* next=copy->next;
        if(cur->random==NULL)
        {
            copy->random=NULL;
        }
        else
        {
            copy->random=cur->random->next;
        }
        cur=next;
    }
    cur=head;
    struct Node* newhead=NULL,*tail=NULL;
    while(cur)//将复制完后的链表取下
    {
        struct Node* copy=cur->next;
        struct Node* next=copy->next;//保存原链表的next值
        if(newhead==NULL)//尾插
        {
            newhead=tail=copy;
        }
        else
        {
            tail->next=copy;
            tail=tail->next;
        }
        cur->next=next;//恢复原链表
        cur=next;//往下走
    }
    return newhead;//返回新节点
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/163860.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java 11及更高版本的Oracle JDK版本

2021 年 9 月 14 日,Oracle 发布了可以长期支持的 JDK17 版本,那么从 JDK11 到 JDK17,到底带来了哪些特性呢?亚毫秒级的 ZGC 效果到底怎么样呢?值得我们升级吗?而且升级过程会遇到哪些问题呢?带…

PyTorch微调权威指南3:使用数据增强

如果你曾经参与过 PyTorch 模型的微调,可能会遇到 PyTorch 的内置变换函数,这使得数据增强变得轻而易举。 即使你之前没有使用过这些功能,也不必担心。 在本文中,我们将深入研究 PyTorch 变换换函数的世界。 我们将探索你可以使用…

Ubuntu20.04 安装微信 【deepin-wine方式极简安装】推荐,两行命令就解决了。

参考git仓库地址: GitHub - zq1997/deepin-wine: 【deepin源移植】Debian/Ubuntu上最快的QQ/微信安装方式【deepin源移植】Debian/Ubuntu上最快的QQ/微信安装方式. Contribute to zq1997/deepin-wine development by creating an account on GitHub.https://github.com/zq199…

指针与多维数组练习

例题一: 矩阵相乘 首先,如果你没学过线代的话,这边建议你去B站把宋浩的矩阵运算学了再来看题 如果有个矩阵A和一个矩阵B,当A的列数和B的行数相同时,生成一个新矩阵C,且C是通过矩阵乘法得来的 A[3][2]{3…

Schrodinger Shape Screen 工具使用方法

schrodinger的shape screen方法是一种基于ligand的筛选方法。需要提供一个参考分子,和需要筛选的分子库。shape screen可以根据原子类型、药效团对分子的形状相似度进行打分。 shape screen面板 shape screen面板如下: 1. 参考分子来源,可以…

【Linux】C文件系统详解(三)——如何理解缓冲区以及自主封装一个文件接口

文章目录 如何理解缓冲区现象概念:文件缓冲区为什么要有缓冲区缓冲区在哪里 自己封装一个简单的文件接口自主封装目标 代码关于缓冲区强制刷新内核 关于字符串格式化函数printf和scanf函数 如何理解缓冲区 以前写过一个进度条, 有一个输出缓冲区->这个缓冲区在哪里,为什么要…

十三、Linux文件目录指令

pwd 指令 基本语法:pwd (功能描述:显示当前工作目录的绝对路径) 应用实例:案例:显示当前工作目录的绝对路径 ls 指令 基本语法:ls 【选项】【目录或是文件】 常用选项 -a :显示当…

卡片排列-第15届蓝桥第二次STEMA测评Scratch真题精选

[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第159讲。 第15届蓝桥杯第2次STEMA测评已于2023年10月29日落下帷幕,编程题一共有6题,分别如下&…

最强人工智能ChatGPT引领AIGC发展

从公众号转载,关注微信公众号掌握更多技术动态 --------------------------------------------------------------- ——AI不会淘汰所有人,但会淘汰不懂AI的人 一、最强人工智能GPT-4 Turbo 在前不久的OpenAI开发者大会,正值Chatgpt3.5发布一…

UDS 14229-1定义的请求的响应行为

UDS服务响应规则 重要提示服务器一般响应行为包含子功能的请求响应行为物理寻址请求功能寻址请求 没有子功能参数的服务响应行为物理寻址客户端请求功能寻址客户端请求 伪代码示例 重要提示 服务应当支持物理寻址方式请求,部分服务也支持功能寻址方式请求。在功能寻…

Java集合大总结——List的简单使用

List简单介绍 鉴于Java中数组用来存储数据的局限性,我们通常使用java.util.List替代数组List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引。JDK API中List接口的实现类常用的有:ArrayList、LinkedList和Vector。 List…

五、Linux目录结构

1.基本介绍 1.Linux的文件系统是采用级层式的树状目录结构,在此结构中的最上层是根目录"r/",然后在此目录下再创建其他的目录。 2.深刻理解linux树状文件目录是非常重要的 3.记住一句经典的话:在Linux世界里,一切皆文件…

asp.net智能考试系统VS开发sqlserver数据库web结构c#编程计算机网页项目

一、源码特点 asp.net 智能考试系统 是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。 系统运行视频 https://www.bilibili.com/video/BV1gz4y1A7Qp/ 二、功能介绍 本系统使用Microsoft Visual Studio 201…

4.6每日一题(多元函数的隐函数求导)

三元方程确定的二元函数类型的隐函数 方法一:两边对x求偏导,把y看成常数 注:z可以把x和y同时代入求出答案 方法二:带公式

Linux tc 使用

tc模拟延时丢包等网络故障依赖的内核驱动 /lib/modules/5.15.0-52-generic/kernel/net/sched/sch_netem.ko有些系统并不是默认就安装上该驱动的,如果没有安装该驱动,构造网络故障时会报错。 root:curtis# tc qdisc change dev enp4s0 root netem delay…

油猴脚本(JavaScript)-练手-简单的随机音乐播放器

浅浅的写个简单的随机音乐播放脚本(可移动),注释很详细,直接上源码 效果: // UserScript // name 播放音乐脚本 // namespace 代码对我眨眼睛 // version 1.2 // description 在API上请求音乐链接并随机自动连续播放音乐&…

斯坦福机器学习 Lecture1

https://www.bilibili.com/video/BV1JE411w7Ub?p1&vd_source7a1a0bc74158c6993c7355c5490fc600 笔记如下 机器学习的定义:不需要明确编程就能让计算机去学习做某件事情 另一个定义 TODO:here

【网络】OSI模型 与 TCP/IP模型 对比

一、OSI模型 OSI模型包含7个层次,从下到上分别是: 1. 物理层(Physical Layer) - 功能:处理与电子设备物理接口相关的细节(如电压、引脚布局、同步,等等)。 - 协议:以…

clusterProfiler包学习

&#x1f4d6; Introduction | Biomedical Knowledge Mining using GOSemSim and clusterProfiler (yulab-smu.top) 部分使用 #GO classificationlibrary(clusterProfiler) data(geneList, package"DOSE") gene <- names(geneList)[abs(geneList) > 2]# Entre…