32 随机链表的复制

随机链表的复制

    • 题解1 哈希表
    • 题解2 回溯+哈希
      • 哈希思路精简
    • 题解3 优化迭代

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

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

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

返回复制链表的头节点。

用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

val:一个表示 Node.val 的整数。
random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null
你的代码 只 接受原链表的头节点 head 作为传入参数。
在这里插入图片描述
提示:

  • 0 <= n <= 1000
  • − 1 0 4 -10^4 104 <= Node.val <= 1 0 4 10^4 104
    Node.randomnull 或指向链表中的节点。
    注意:本题与主站 138 题相同:138

题解1 哈希表

/*
// Definition for a Node.
class Node {
public:int val;Node* next;Node* random;Node(int _val) {val = _val;next = NULL;random = NULL;}
};
*/class Solution {
public:Node* copyRandomList(Node* head) {if(! head) return nullptr;Node *p, *q, *f, *cphead;f = p = q = new Node(head->val);cphead = head;/** 受判题启发:给结点编号(array-like)1. 变量需要3个map,分别记录结点-编号,编号-地址/结点,结点编号-其随机结点编号2. 关键问题是:随机结点是在整个链表的基础上去看,即next建立了一条完整的链表,之后才有random的关系,即random结点是已经存在的结点,不能再new了**/unordered_map<Node*, int> idxmap;unordered_map<int, Node*> addrmap;unordered_map<int, int> randomidxmap;/** 对空特殊处理(可以让idx从1开始,避开0)int idx = 0;idxmap[nullptr] = 1001;randomidxmap[idxmap[nullptr]] = idxmap[nullptr];addrmap[randomidxmap[idxmap[nullptr]]] = nullptr;**/int idx = 1;// 结点编号,建立新链表while(head){idxmap[head] = idx;idxmap[q] = idx;addrmap[idx] = q;head = head->next;if(head)q->next = new Node(head->val);else q->next = nullptr;q = q->next;idx ++;}// 记录原链表的random关系while(cphead){randomidxmap[idxmap[cphead]] = idxmap[cphead->random];cphead = cphead->next;}// 复刻while(p){p->random = addrmap[randomidxmap[idxmap[p]]];p = p->next;}return f;}
};

在这里插入图片描述

题解2 回溯+哈希

class Solution {
public:// key = 原结点// value = 新结点unordered_map<Node*, Node*> Nodemap;Node* copyRandomList(Node* head) {if(! head) return nullptr;// 需要克服的问题是:不知道random指向的结点是否建立过	// 如果没建立过,则新建if(! Nodemap.count(head)){Node* newnode = new Node(head->val);Nodemap[head] = newnode;newnode->next = copyRandomList(head->next);newnode->random = copyRandomList(head->random); }// 建立过直接返回return Nodemap[head];}
};

在这里插入图片描述

哈希思路精简

class Solution {
public:Node* copyRandomList(Node* head) {if(! head) return nullptr;map<Node*, Node*> kkmap;Node* autohead = head;// 新建链表// kkmap保证每个结点对应的都是新地址while(autohead){kkmap[autohead] = new Node(autohead->val);autohead = autohead->next;}autohead = head;// 建立next和random关系while(autohead){kkmap[autohead]->next = kkmap[autohead->next];kkmap[autohead]->random = kkmap[autohead->random];autohead = autohead->next;}return kkmap[head];}
};

在这里插入图片描述

题解3 优化迭代

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class Solution {
public:Node* copyRandomList(Node* head) {if(! head) return nullptr;Node* ll = head;Node* newhead;// copy to the original linkwhile(ll){Node* nextll = ll->next;Node* tmp = new Node(ll->val);ll->next = tmp;tmp->next = nextll;ll = nextll;}// Handle random point First !!!!(next info exists)ll = head;while(ll){Node* cphead = ll->next;cphead->random = ll->random ? ll->random->next : nullptr;ll = cphead->next;}newhead = head->next;ll = head;// Handle next point and restore the original onewhile(ll){Node* cphead = ll->next;// 断开连接ll->next = cphead->next;cphead->next = cphead->next ? cphead->next->next : nullptr;ll = ll->next;}return newhead;}
};

在这里插入图片描述

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

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

相关文章

OR54 字符串中找出连续最长的数字串

目录 一、题目 二、解答 &#xff08;一&#xff09;问题一&#xff1a;在记录完一组连续字符串后&#xff0c;没有注意判别紧随其后的非数字字符 &#xff08;二&#xff09;问题二&#xff1a;越界访问 &#xff08;三&#xff09;正确 一、题目 字符串中找出连续最长的…

设计模式再探——原型模式

目录 一、背景介绍二、思路&方案三、过程1.原型模式简介2.原型模式的类图3.原型模式代码4.原型模式深度剖析5.原型模式与spring 四、总结五、升华 一、背景介绍 最近在做业务实现的时候&#xff0c;为了通过提升机器来降低开发人员的难度和要求&#xff0c;于是在架构设计…

数据标准化

1、均值方差标准化(Z-Score标准化) 计算过程&#xff1a; 对每个属性/每列分别进行一下操作&#xff0c;将数据按属性/按列减去其均值&#xff0c;并除以其方差&#xff0c;最终使每个属性/每列的所有数据都聚集在均值为0&#xff0c;方差为1附近。 公式&#xff1a;(x-mean(x…

电子信息工程专业课复习知识点总结:(五)通信原理

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 第一章通信系统概述——通信系统的构成、各部分性质、性能指标1.通信系统的组成&#xff1f;2.通信系统的分类&#xff1f;3.调制、解调是什么&#xff1f;有什么用…

【数据结构--排序】堆排序

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

在北京多有钱能称为富

背景 首先声明&#xff0c;此讨论仅限个人的观点&#xff0c;因为我本身不富嘛&#xff0c;所以想法应该非常局限。 举个栗子 富二代问我朋友&#xff0c;100~1000w之间&#xff0c;推荐一款车&#xff1f; 一开始听到这个问题的时候&#xff0c;有被唬住&#xff0c;觉得预…

XXE 漏洞及案例实战

文章目录 XXE 漏洞1. 基础概念1.1 XML基础概念1.2 XML与HTML的主要差异1.3 xml示例 2. 演示案例2.1 pikachu靶场XML2.1.1 文件读取2.1.2 内网探针或者攻击内网应用&#xff08;触发漏洞地址&#xff09;2.1.4 RCE2.1.5 引入外部实体DTD2.1.6 无回显读取文件 3. XXE 绕过3.1 dat…

Nitrux 3.0 正式发布并全面上市

导读乌里-埃雷拉&#xff08;Uri Herrera&#xff09;近日宣布 Nitrux 3.0 正式发布并全面上市&#xff0c;它是基于 Debian、无 systemd、不可变的 GNU/Linux 发行版的最新安装媒体&#xff0c;利用了 KDE 软件。 Nitrux 3.0 由带有 Liquorix 味道的 Linux 6.4.12 内核提供支持…

QT-day4

画一个时钟 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPaintEvent> #include <QDebug> #include <QPainter> #include <QTimer> #include <QTime>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } Q…

记一次逆向某医院挂号软件的经历

背景 最近家里娃需要挂专家号的儿保&#xff0c;奈何专家号实在过于抢手&#xff0c;身为程序员的我也没有其他的社会资源渠道可以去弄个号&#xff0c;只能发挥自己的技术力量来解决这个问题了。 出师不利 首先把应用安装到我已经 Root 过的 Pixel 3 上面&#xff0c;点击应…

关于Pandas数据分析

pandas的数据加载与预处理 数据清洗&#xff1a;洗掉脏数据 整理分析&#xff1a;字不如表 数据展现&#xff1a;表不如图 环境搭建 pythonjupyter anaconda Jupyter Notebook Jupyter Notebook可以在网页页面中直接编写代码和运行代码, 代码的运行结果也会直接在代码块下显示…

【 Ubuntu】systemd服务创建、启用、状态查询、自启等

要在 Ubuntu 启动后执行一个守护脚本&#xff0c;您可以使用 Shell 脚本编写一个 systemd 服务单元。systemd 是 Ubuntu 中常用的服务管理工具&#xff0c;可以在系统启动时自动启动和管理服务。 下面是一个示例的守护脚本和 systemd 服务单元的步骤&#xff1a; 创建守护脚本…

Spring之依赖注入源码解析

基于Autowired的依赖注入底层原理 基于Resource注解底层工作流程图&#xff1a; 1 Spring中到底有几种依赖注入的方式&#xff1f; 首先分两种&#xff1a; 手动注入 自动注入 1.1 手动注入 在XML中定义Bean时&#xff0c;就是手动注入&#xff0c;因为是程序员手动给某…

LeetCode 75-02:字符串的最大公因子

前置知识&#xff1a;使用欧几里得算法求出最大公约数 func gcdOfStrings(str1 string, str2 string) string {if str1str2 ! str2str1 {return ""}return str1[:gcd(len(str1), len(str2))] }func gcd(a, b int)int{if b 0{return a}return gcd(b, a%b) }

车载软件架构 —— AUTOSAR Vector SIP包(二)

车载软件架构 —— AUTOSAR Vector SIP包(二) 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无需有人关注你。你必须承认自己的价值,你不能站在他人的角度来反对自己。人生在…

Android Kotlin 基础详解

1,基础语法 1.1 可变变量与不可变变量 可以多次赋值的变量是可变变量&#xff0c;用关键字var表示&#xff1a; var <标识符> : <类型> <初始化值> 注意&#xff0c;在kotlin中成员变量不会赋默认值&#xff0c;不像java一样&#xff0c;必须手动添加默…

83、SpringBoot --- 下载和安装 MSYS2、 Redis

★ 下载和安装MSYS2&#xff08;作用&#xff1a;可在Windows模拟一个Linux的编译环境&#xff09; 得到Redis的编译环境——在Linux平台上&#xff0c;这一步可以省略。&#xff08;1&#xff09;登录MSYS2官网&#xff08;http://repo.msys2.org/distrib/ &#xff09;下载M…

Java 项目-基于 SpringBoot+Vue的疫情网课管理系统

文章目录 第一章 简介第二章 技术栈第三章 系统分析3.4.2学生用例 第四章 系统设计第五章 系统实现5.1学生功能模块5.2管理员功能模块5.3教师功能模块 六 源码咨询 第一章 简介 疫情网课也都将通过计算机进行整体智能化操作&#xff0c;实现的功能如下。 例如 管理员&#x…

【力扣-每日一题】LCP 06. 拿硬币

class Solution { public:int minCount(vector<int>& coins) {int res0;for(auto i:coins){resi/2;res(i%2)?1:0;}return res;} };

2023 年前端 UI 组件库概述,百花齐放!

UI组件库提供了各种常见的 UI 元素&#xff0c;比如按钮、输入框、菜单等&#xff0c;只需要调用相应的组件并按照需求进行配置&#xff0c;就能够快速构建出一个功能完善的 UI。 虽然市面上有许多不同的UI组件库可供选择&#xff0c;但在2023年底也并没有出现一两个明确的解决…