剑指 Offer 35. 复杂链表的复制

news2024/12/22 18:40:53

题目

请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
在这里插入图片描述
在这里插入图片描述

思路

方法一:哈希表

利用哈希表的查询特点,构建 原链表节点新链表对应节点 的键值对映射关系: <原 cur 节点, 新 cur 节点>,再遍历构建新链表各节点的 nextrandom引用指向即可。

用哈希表dic记录原、新节点的对应关系是为了后续新链表节点的引用指向

流程如下:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
java代码如下:

class Solution {
	public Node copyRandomList(Node head){
		if(head == null) return null;
		Node cur = head;
		Map<Node,Node> map = new HashMap<>();//哈希表用来做原链表节点和新链表节点的映射关系
		 // 复制各节点,并建立 “原节点 -> 新节点” 的 Map 映射
		 while(cur != null){
		 	map.put(cur, new Node(cur.val));
		 	cur = cur.next;
		 }
		 //新链表复制完成后,从头开始构造新链表节点引用指向
		 cur = head;//从头结点开始
		 //构建新链表的next和random指向
		 while(cur != null){
		 	map.get(cur).next = map.get(cur.next);//map.get(cur)相当于是从哈希表中获取新链表节点cur',cur为key,获得的是value即新链表节点
		 	map.get(cur).random = map.get(cur.random);
		 	cur = cur.next;
		 }
		 //返回新链表的头结点
		 return map.get(head);
	}
}

方法二:拼接 + 拆分

考虑构建 原节点 1 -> 新节点 1 -> 原节点 2 -> 新节点 2 -> …… 的拼接链表,如此便可在访问原节点的 random 指向节点的同时找到新对应新节点的 random 指向节点。

  1. 复制各节点,构建拼接链表:原节点 1 -> 新节点 1 -> 原节点 2 -> 新节点 2 -> ……
  2. 构建新链表各节点的random指向:当访问原节点 cur 的随机指向节点 cur.random 时,对应新节点 cur.next 的随机指向节点为 cur.random.next
  3. 拆分原 / 新链表:设置 pre / cur 分别指向原 / 新链表头节点,遍历执行 pre.next = pre.next.nextcur.next = cur.next.next 将两链表拆分开
  4. 返回新链表的头节点 res 即可

流程图如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

java代码如下:

class Solution {
	public Node copyRandomList(Node head){
		if(head == null) return null;
		Node cur = head;
		//1.复制各节点,并构建拼接链表(相当于创建一个值等于原节点的新节点并插入进去)
		while(cur != null){
			Node tmp = new Node(cur.val);//创建相同值的新节点
			//在原节点后插入新节点
			tmp.next = cur.next;
			cur.next = tmp;
			//继续插入下一个新节点
			cur = tmp.next;
		}
		// 2. 构建各新节点的 random 指向
		cur = head;
		while(cur != null){
			if(cur.random != null){
				cur.next.random = cur.random.next;//cur.next表示cur对应的新节点,cur.random.next表示cur.random对应的新节点
			}
			cur = cur.next.next;
		}
		// 3. 拆分两链表
		cur = head.next;
		Node pre = head;
		Node res = head.next;//保存新链表头节点,用于最后返回
		while(cur.next != null){
			pre.next = pre.next.next;
			cur.next = cur.next.next;
			//继续往后判断
			pre = pre.next;
			cur = cur.next;
		}
		pre.next = null;//单独处理原链表尾节点
		return res;//返回新链表头节点
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】项目自动化构建工具-make/Makefile与Linux调试器-gdb使用

文章目录Linux项目自动化构建工具-make/MakefileLinux调试器-gdb使用Linux项目自动化构建工具-make/Makefile 背景 会不会写makefile&#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放在若干个目录…

SpringBoot+Vue图书馆管理系统

简介&#xff1a;本项目采用了基本的SpringBootVue设计的图书馆管理系统。详情请看截图。经测试&#xff0c;本项目正常运行。本项目适用于Java毕业设计、课程设计学习参考等用途。 项目描述 项目名称SpringBootVue图书馆管理系统源码作者LHL项目类型Java EE项目 &#xff08;…

【iMessage苹果推推送】将看到一个可扩大选项“AppleDevelopmentPushServices”6.扩展此选项并右键单击“Appledge”>

推荐内容IMESSGAE相关 作者✈️IMEAX推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容3.日历推 *** …

基于NOSTR协议的“公有制”版本的Twitter,去中心化社交软件Damus用后感,一个极端走向另一个极端

最近&#xff0c;一个幽灵&#xff0c;Web3的幽灵&#xff0c;在网络游荡&#xff0c;它叫Damus&#xff0c;这玩意诠释了什么叫做病毒式营销&#xff0c;滑稽的是&#xff0c;一个Web3产品却在Web2的产品链上疯狂传销&#xff0c;各方大佬纷纷为其背书&#xff0c;到底发生了什…

基于python实现疫情期间微博、B站网民情绪分析

一项目概述&#xff1a;“疫情下的社会心理学”这一课题旨在通过疫情期间大众在自媒体上的新闻评论等信息&#xff0c;凭借一些方法分析出总体的心理变化和情绪走向&#xff0c;并在宏观上把握了总体的心态格局。对于该课题&#xff0c;我们小组首先爬取了哔哩哔哩和微博的大量…

Spring Boot(三):第二种导入依赖方式的实战案例(常用)

文章目录 第二种导入依赖方式的实战案例 一、导入依赖方式1&#xff08;拓展方法&#xff09; 二、使用idea自带springBoot项目初始化插件 第二种导入依赖方式的实战案例 一、导入依赖方式1&#xff08;拓展方法&#xff09; 在公司中可能会出现必须继承某个项目&#xff…

Linux日志分析工具之AWStats

Linux日志分析工具之AWStats &#x1f4d2;博客主页&#xff1a; 微笑的段嘉许博客主页 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐留言&#x1f4dd; &#x1f4cc;本文由微笑的段嘉许原创&#xff01; &#x1f4c6;CSDN首发时间&#xff1a;&#x1f334;2…

力扣sql简单篇练习(十)

力扣sql简单篇练习(十) 1 过去30天的用户活动 || 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 a 示例输入 b 示例输出 1.2 示例sql语句 # 多少天内使用Date_SUB函数,具体用法是Date_SUB(初始日期,interval 变更的天数 day) ,正数找过去负数找未来 # 变更天数多少…

接口测试、接口协议以及常用接口测试工具介绍

目录 一、前言&#xff1a;什么是接口 二、接口协议以及对应的接口测试工具 三、接口测试如何设计测试用例&#xff1f; 四、接口组成&#xff1f; 五、总结 一、前言&#xff1a;什么是接口 1.接口指的是软件提供给外界的一种服务。作用在于使其内部的数据能被外部进行修…

买的香港云服务器怎么用?云服务器使用教程

香港云服务器的优势及好处&#xff0c;使得很多人都愿意使用和推荐&#xff0c;推荐的人多了自然购买的人就多了&#xff0c;其中不乏很大部分新手&#xff0c;购买之后却不知道该怎么使用和管理登录等操作。下面我们聊聊香港云服务器怎么登录使用。 香港云服务器登录管理方法&…

论文浅尝 | 基于无监督标注的漏洞描述文本概念抽取

笔记整理&#xff1a;韩林峄&#xff0c;天津大学博士论文发表期刊&#xff1a;Transactions on Software Engineering and Methodology (TOSEM)动机软件漏洞对推进漏洞分析和安全研究具有巨大的潜力&#xff0c;人们往往使用自然语言来描述软件漏洞的关键特征&#xff0c;并在…

JAVA打印数字二进制编码逻辑说明

在我们学习算法的过程中&#xff0c;我们首先必须要知道的就是数据(尤其是数字)类型在底层保存的方式。因为这样才能使我们的算法变的更加高效。 在JAVA中我们常用的数字类型是int类型&#xff0c;有过基础的同学应该知道int数据类型的长度为32bit。但实际使用时需要注意只有3…

11 |「哈希表」简析

前言 前言&#xff1a;刷「哈希表」高频面试题。 文章目录前言一、简介1、离散化1&#xff09;什么是离散化2&#xff09;离散化存储3&#xff09;离散化映射2、哈希表1&#xff09;什么是哈希表2&#xff09;哈希表存储3&#xff09;哈希函数4&#xff09;哈希冲突二、参考链接…

Python爬取网页Flex渲染的动态内容

我最近使用Python爬取网页内容时遇到Flex渲染的动态页面&#xff0c;比如下图的课程目录标题&#xff0c;此时按鼠标右键&#xff0c;菜单里没有复制链接的选项。 目的&#xff1a;获取各个视频标题、链接。 按F12进入开发者模式分析网页&#xff0c;可见有多个flex标签&#…

通用视觉框架OpenMMLab图像分类与基础视觉模型

文章目录流程传统方法&#xff1a;设计图像特征(1990s~2000s)特征工程的天花板从特征工程到特征学习层次化特征的实现方式AlexNet 的诞生& 深度学习时代的开始图像分类的数学表示AlexNet (2012)Going Deeper (2012~2014)VGG (2014)GoogLeNet (Inception v1, 2014)精度退化问…

ROS2 基础概念 动作

ROS2 基础概念 动作1. Actions2. 动作3. 中止目标4. 动作类型5. 动作请求1. Actions Actions 动作是ROS 2中的通信类型之一&#xff0c;适用于长时间运行的任务 它们由三部分组成&#xff1a;目标、反馈 和 结果&#xff0c;操作基于话题和服务 它们的功能类似于服务&#xff…

【大数据clickhouse】clickhouse 数据一致性保障常用解决方案

一、前言 对于任何一个数据存储的框架来说&#xff0c;确保数据的一致性都是其非常重要的组成部分&#xff0c;不管是过程中的强一致性&#xff0c;还是最终一致性&#xff0c;都是数据一致性的解决方案&#xff0c;本篇来聊聊clickhouse中的数据一致性问题。 二、clickhouse …

JMeter使用BeanShell断言

BeanShell简介BeanShell是使用Java语法的一套脚本语言&#xff0c;在JMeter的多种组件中都有BeanShell的身影&#xff0c;如&#xff1a;定时器&#xff1a;BeanShell Timer前置处理器&#xff1a;BeanShell PreProcessor采样器&#xff1a;BeanShell Sampler后置处理器&#x…

软件的生命周期(软件工程各阶段的工作)

其实软件工程是一个非常大的概念&#xff0c;我们的软件测试也好&#xff0c;软件开发也好&#xff0c;软件运维也好&#xff0c;其实都是属于软件工程的范畴。 今天就讲一讲软件工程和我们软件测试相关的一些内容。 我们今天三个主要的节点&#xff1a; 1.软件的生命周期 至…

QT中级(1)QTableView自定义委托(一)实现QSpinBox、QDoubleSpinBox委托

1 写在前面的话 我们在之前写的《QT(7)-初识委托》文章末尾提到&#xff0c;“使用一个类继承QStyledItemDelegate实现常用的控件委托&#xff0c;在使用时可以直接调用接口&#xff0c;灵活实现各种委托”。我们接下来几篇文章将先详细讲解各个控件的委托&#xff0c;最后整理…