【初阶数据结构】单链表经典OJ题

ops/2024/10/18 19:23:23/

目录标题

  • 原题展现
  • 题目解析
  • 代码展现
    • 1.创建新节点
    • 2.拷贝random指针
    • 3.将新节点尾插

请添加图片描述

原题展现

  该题是力扣上的第138题,题目链接如下:随机链表的复制。
在这里插入图片描述
在这里插入图片描述

题目解析

  我们发现这个链表和一般的链表存在着一点点区别,那就是每个节点多了一个random指针,它指向的是随机的节点。题目要求我们构造原链表的深拷贝,简单的说就是构造一个新的链表,要求这两个链表是要一摸一样,包括里面的值和指针。
  我们发现,如果链表中不存在random指针时,该链表的拷贝是非常简单的,但是这个链表中存在了random这个指针,且random指向随机,那么我们在拷贝时也不太好拷贝。此时我们就要想一个办法让我们在拷贝时能让新节点快速找到random指向的节点。
  此时我们可以将拷贝节点插入在原节点的后面,这样使得拷贝节点和原节点建立了一个关联关系。
在这里插入图片描述
  我们将新节点插入完之后,开始将random指针进行拷贝,我们发现,原链表的蓝1这个节点的random指向蓝2这个节点,此时我们同样要让绿1这个节点指向绿2这个节点,我们可以找到拷贝节点和原节点之间存在的一个关系:新节点->random = 原节点->random->next也就是新节点的random要指向的节点是原节点的random节点的下一个节点。
在这里插入图片描述
  此时,我们就可以通过循环,将每个新节点加入random指针,使其指向正确的新的节点,最后将这些新拷贝好的节点一个个尾插就能组成一个新的链表。

代码展现

  我们要理清思路,才能更好地写代码,根据该题,我们就能分几个步骤:

  1. 创建新节点插入到每个节点的后面
  2. 根据原节点的random拷贝到新节点中
  3. 将新节点拿下来尾插成为新链表

1.创建新节点

    Node* pcur = head;while(pcur){Node* copy = (Node*)malloc(sizeof(Node));copy->val = pcur->val;copy->next = pcur->next;pcur->next = copy;pcur = copy->next;}

使用malloc创建新节点,并将原节点的值同样赋给新节点
并且将新节点插入到原节点后面

2.拷贝random指针

    pcur = head;while(pcur){Node* copy = pcur->next;if(pcur->random != NULL){copy->random = pcur->random->next;}else{copy->random = NULL;}pcur = pcur->next->next;}

让pcur重新指向头结点循环
先要判断pcur->random是否为空
新节点的random要指向的节点是原节点的random节点的下一个节点

3.将新节点尾插

    pcur = head;Node* copyhead = NULL, *copytail = NULL;while(pcur){Node* next = pcur->next->next;if(copytail == NULL){copyhead = copytail = pcur->next;}else{copytail->next = pcur->next;copytail = copytail->next;}pcur = next;}

建立新的链表,将新节点尾插到新链表中
尾插后可以将原链表复原,只需在pcur = next前加一句pcur->next = next;(不复原也可以)

  至此,这道题目结束,下面是完整代码:

/*** Definition for a Node.* struct Node {*     int val;*     struct Node *next;*     struct Node *random;* };*/typedef struct Node Node;
struct Node* copyRandomList(struct Node* head) {Node* pcur = head;while(pcur){Node* copy = (Node*)malloc(sizeof(Node));copy->val = pcur->val;copy->next = pcur->next;pcur->next = copy;pcur = copy->next;}pcur = head;while(pcur){Node* copy = pcur->next;if(pcur->random != NULL){copy->random = pcur->random->next;}else{copy->random = NULL;}pcur = pcur->next->next;}pcur = head;Node* copyhead = NULL, *copytail = NULL;while(pcur){Node* next = pcur->next->next;if(copytail == NULL){copyhead = copytail = pcur->next;}else{copytail->next = pcur->next;copytail = copytail->next;}pcur = next;}return copyhead;
}

  本道题的讲解到此结束,感谢大家观看,如果大家喜欢,希望大家一键三连支持一下,如有表述不正确,也欢迎大家批评指正。
请添加图片描述


http://www.ppmy.cn/ops/38919.html

相关文章

Visual Studio和Visual Studio Code适用于哪些编程语言

Visual Studio和Visual Studio Code都适用于多种编程语言,它们的适用编程语言如下: Visual Studio适用于: C#Visual Basic .NETF#CJavaScriptTypeScriptPythonHTML/CSSJava(通过插件支持) Visual Studio Code适用于…

flutter 在onError函数中不推荐使用“runZoned

当我在main.dart文件上使用最新的Flutter v1.17.1和Dart 2.8.2版本时,我收到了这个错误消息, onError‘是不建议使用的,不应该使用。使用runZonedGuarded代替。尝试用替换替换不推荐的成员的使用。 这是CODE, 代码语言&#xf…

从需求到实现的关键

版本封面 内容:产品logo,项目名称,所属公司,产品名称,文档类型,版本号,时间,相关人员(最好说明下负责人)。 作用: 突出重要信息,将…

针对macOS上的maven安装配置

这篇博客将向读者介绍如何安装和配置Maven。Maven是一个强大的项目管理工具,广泛用于Java项目的构建、依赖管理和项目报告生成。它可以极大地简化项目的构建过程,并帮助开发人员管理项目的各种依赖项。 什么是Maven? Maven是一个基于项目对…

计算机网络【应用层】邮件和DNS

文章目录 电子邮件DNSDNS提供的服务:域名分级域名解析流程DNS资源记录DNS服务器类型 电子邮件 使用SMTP协议发送邮件之前,需要将二进制多媒体数据编码为ASCII码SMTP一般不使用中间邮件服务器发送邮件,如果收件服务器没开机,那么会…

【二分查找 滑动窗口】100257找出唯一性数组的中位数

本文涉及知识点 二分查找算法合集 C算法:滑动窗口总结 LeetCode 100257找出唯一性数组的中位数 给你一个整数数组 nums 。数组 nums 的 唯一性数组 是一个按元素从小到大排序的数组,包含了 nums 的所有非空子数组中不同元素的个数。 换句话说&#xf…

Docker安装达梦数据库

1.确保已安装Docker 可参考:Linux安装Docker-CSDN博客 2.上传dm镜像并导入安装包 可以从:产品下载 | 达梦数据库下载dm镜像,如下图: docker load -i dm8_20230808.tar 3.导入后查看镜像 docker images 4.启动容器 docker run …

Java毕业设计 基于SpringBoot vue新能源充电系统

Java毕业设计 基于SpringBoot vue新能源充电系统 SpringBoot 新能源充电系统 功能介绍 首页 图片轮播 充电桩 充电桩类型 充电桩详情 充电桩预约 新能源公告 公告详情 登录注册 个人中心 余额充值 修改密码 充电桩报修 充电桩预约订单 客服 后台管理 登录 个人中心 修改密码…