复制带随机指针的链表【构造链表深拷贝】

复制带随机指针的链表 

文章目录

复制带随机指针的链表 

链表复制要求

解题思路

1、拷贝所有节点,并放在对应原节点的后面

2.将每个 random 指向对应的位置。

3.将复制的链表解下来,尾插到一起,并将原链表恢复

源码


  先导知识点:单链表 

复制带随机指针链表的要求

  给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。

  要求:时间复杂度O(N),空间复杂度O(1)

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

val 是一个整数

next 指向下一个节点

random 指向任意一个节点 

  例如下面的链表,这个链表复制得到的链表除了每个节点的地址与此链表不同,其他部分必须与这个链表完全相同。

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]

输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

解题思路

  此题对时间复杂度和空间复杂度都有了限制,因此不能采用暴力求解的方式。

  难点:节点的 random 指针是指向随机的节点,不能使用传统思维模式,所以原始的拷贝链表的方法如果用在这里的话,可能无法处理后续问题。

  对于此题采用的方法如下:

  • 拷贝所有节点,放在对应原节点的后面。
  • 将每个 random 指向对应的位置。
  • 将复制的链表解下来,尾插到一起,并将原链表恢复。

  每个阶段使用完 cur 都要记得将 cur 置为 head 。

1、拷贝所有节点,并放在对应原节点的后面

每次开辟节点复制并直接尾插在原节点后面即可。

2.将每个 random 指向对应的位置。

  当将每个节点的复制节点尾插在原节点的后面之后,那么原节点的 random指向的位置的下一个节点,就是复制后节点的 random 指针要指向的位置

3.将复制的链表解下来,尾插到一起,并将原链表恢复

先将复制的链表解下来

  定义两个链表 copyhead copytail,copyhead 记录新链表的头节点,copytail 负责维护新节点尾插。用copytail 维护尾插的好处是不用每次循环找尾,只需要每次 copytail 后移即可。

然后再将原链表恢复,恢原链表只需要将链表的 next 指向下一个next就可以了。

源码

struct Node* copyRandomList(struct Node* head) {struct Node* cur = head;while (cur != NULL){struct Node* copy = (struct Node*)malloc(sizeof(struct Node));struct Node* next = cur->next; copy->val = cur->val;cur->next = copy;copy->next = next;cur = next; }cur = head;while (cur != NULL){struct Node* copy = cur->next;if (cur->random == NULL)copy->random = NULL;else{copy->random = cur->random->next;}cur = copy->next;}cur = head;struct Node* copyhead = NULL, * copytail = NULL;while (cur != NULL){struct Node* copy = cur->next;struct Node* next = copy->next;if (copytail == NULL){copyhead = copytail = copy;}else{copytail->next = copy;copytail = copytail->next;}cur->next = next;cur = next;}return copyhead;
}

这段代码是力扣的核心代码模式,返回复制成功的链表头节点即可。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis关联查询

文章目录 前言多对一关联 association一对多关联 collection 前言 提示:这里可以添加本文要记录的大概内容: 关联查询是指在一个查询中同时获取多个表中的数据,将它们结合在一起进行展示。 关联表需要两个及以上的表 数据库代码&#xff1…

深入理解负载均衡原理及算法

1. 前言 在互联网早期,网络还不是很发达,上网用户少,流量相对较小,系统架构以单体架构为主。但如今在互联网发达的今天,流量请求动辄百亿、甚至上千亿,单台服务器或者实例已完全不能满足需求,这就有了集群。不论是为了实现高可用还是高性能,都需要用到多台机器来扩展服…

如何安装、部署、启动Jenkins

一、测试环境 Linux系统 Centos 7 二、安装步骤: 1、安装jdk 我安装的是jdk8,此处就不多说了,自己百度哈,很简单 2、安装jenkins 首先依次执行如下三个命令: 2.1、导入镜像: [rootcentos7 ~]# sudo …

目标检测中的IOU

IOU 什么是IOU?IOU应用场景写代码调试什么是IOU? 简单来说IOU就是用来度量目标检测中预测框与真实框的重叠程度。在图像分类中,有一个明确的指标准确率来衡量模型分类模型的好坏。其公式为: 这个公式显然不适合在在目标检测中使用。我们知道目标检测中都是用一个矩形框住…

测试人员简单使用Jenkins

一、测试人员使用jenkins干什么? 部署测试环境 二、相关配置说明 一般由开发人员进行具体配置 1.Repository URL:填写git地址 2.填写开发分支,测试人员可通过相应分支进行测试环境的构建部署 当多个版本并行时,开发人员可以通过…

嵌入式开发学习(STC51-9-led点阵)

内容 点亮一个点; 显示数字; 显示图像; LED点阵简介 LED 点阵是由发光二极管排列组成的显示器件 通常应用较多的是8 * 8点阵,然后使用多个8 * 8点阵可组成不同分辨率的LED点阵显示屏,比如16 * 16点阵可以使用4个8 *…

MySQL常见问题处理(三)

MySQL 常见问题解决 夕阳留恋的不是黄昏,而是朝阳 上一章简单介绍了MySQL数据库安装(二), 如果没有看过, 请观看上一章 一. root 用户密码忘记,进行重置操作 复制内容来源链接: https://blog.csdn.net/weixin_48927364/article/details/123556927 一.…

2023华数杯数学建模C题思路分析 - 母亲身心健康对婴儿成长的影响

# 1 赛题 C 题 母亲身心健康对婴儿成长的影响 母亲是婴儿生命中最重要的人之一,她不仅为婴儿提供营养物质和身体保护, 还为婴儿提供情感支持和安全感。母亲心理健康状态的不良状况,如抑郁、焦虑、 压力等,可能会对婴儿的认知、情…

BI报表工具有哪些作用?奥威BI全面剖析数据

BI报表工具有哪些作用?主要的作用是通过整合多业务来源数据,全面分析挖掘数据,来帮助企业实现数据化运营、支持智能决策、实现数据资产沉淀和增值、进行数据挖掘和预测分析、提高数据可读性和数据可视化程度等,从而提高企业的竞争…

Unity 编辑器选择器工具类Selection 常用函数和用法

Unity 编辑器选择器工具类Selection 常用函数和用法 点击封面跳转下载页面 简介 在Unity中,Selection类是一个非常有用的工具类,它提供了许多函数和属性,用于操作和管理编辑器中的选择对象。本文将介绍Selection类的常用函数和用法&#xff…

该选择WPF 还是 Winform?

WPF和WinForms都是.NET平台下的桌面应用程序开发框架,它们各有特点,适用于不同的场景和需求。下面是对WPF和WinForms的一些比较和优劣势:WPF(Windows Presentation Foundation):WPF具有强大的图形渲染能力&…

QT图形视图系统 - 使用一个项目来学习QT的图形视图框架 - 终篇

QT图形视图系统 - 终篇 接上一篇,我们需要继续完成以下的效果; 先上个效果图: 修改背景,使之整体适配 上一篇我们绘制了标尺,并且我们修改了放大缩小和对应的背景,整体看来,我们的滚动条会和…