当前位置:网站首页>剑指Offer 35.复杂链表的复制
剑指Offer 35.复杂链表的复制
2022-08-02 03:33:00 【HotRabbit.】
题目
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
示例 1:

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

输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]
示例 3:

输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]
示例 4:
输入:head = []
输出:[]
解释:给定的链表为空(空指针),因此返回 null。
提示:
-10000 <= Node.val <= 10000Node.random为空(null)或指向链表中的节点。- 节点数目不超过 1000 。
**注意:**本题与主站 138 题相同:https://leetcode-cn.com/problems/copy-list-with-random-pointer/
Related Topics
- 哈希表
- 链表
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/fu-za-lian-biao-de-fu-zhi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
复制的时候,不确定 next、random 节点是否已经被创建了
题解
回溯+哈希表
- 用哈希表记录每一个节点对应新节点的创建情况。遍历该链表的过程中,检查「当前节点的后继节点」和「当前节点的随机指针指向的节点」的创建情况
- 如果这两个节点中的任何一个节点的新节点没有被创建,我们都立刻递归地进行创建。
- 当我们拷贝完成,回溯到当前层时,我们即可完成当前节点的指针赋值。
- 由于一个节点可能会被多个节点指向,为了防止重复拷贝,我们需要首先检查当前节点是否被拷贝过,如果已经拷贝过,我们可以直接从哈希表中取出拷贝后的节点的指针并返回即可。
class Solution {
Map<Node,Node> cacheNodes = new HashMap<>();
public Node copyRandomList(Node head) {
if (head == null){
return null;
}
if (!cacheNodes.containsKey(head)){
Node headNew = new Node(head.val);
cacheNodes.put(head,headNew);
headNew.next = copyRandomList(head.next);
headNew.random = copyRandomList(head.random);
}
return cacheNodes.get(head);
}
}
迭代+节点分拆
- 将每一个节点之后加一个响应的复制的节点,即:A→B→C ==》 A→A′→B→B′→C→C′
- 这样子,每个节点的随机节点就都建立成功了
- 这样,我们可以直接找到每一个拷贝节点 S′ 的随机指针应当指向的节点,即为其原节点 S 的随机指针指向的节点 T 的后继节点 T′。
- 当我们完成了拷贝节点的随机指针的赋值,我们只需要将这个链表按照原节点与拷贝节点的种类进行拆分即可,只需要遍历一次。

class Solution {
Map<Node,Node> cacheNodes = new HashMap<>();
public Node copyRandomList(Node head) {
if (head == null){
return null;
}
//复制每个节点
for (Node node = head;node != null;node = node.next.next){
Node copyNode = new Node(node.val);
copyNode.next = node.next;
node.next = copyNode;
}
//链表的分割
//随机节点的复制
for (Node node = head;node != null;node = node.next.next){
Node copyNode = node.next;
copyNode.random = (node.random == null) ? null : node.random.next;
}
//后继节点的复制
Node newNode = head.next;
for (Node node = head;node != null;node = node.next){
Node copyNode = node.next;
node.next = node.next.next;
copyNode.next = (copyNode.next == null) ? null : copyNode.next.next;
}
return newNode;
}
}
边栏推荐
- ICN6211:MIPI DSI转RGB视频转换芯片方案介绍 看完涨知识了呢
- 【网络基础】浏览器输入一个URL之后,都发生了什么(详细讲解)
- [Arduino connected to GPS module (NEO-6M) to read positioning data]
- Process (below): process control, termination, waiting, replacement
- 所有子字符串中的元音 —— LeetCode - 2063
- 联阳IT6561|IT6561FN方案电路|替代IT6561方案设计DP转HDMI音视频转换器资料
- Typora use
- 机械臂运动学解析
- 【plang1.4.3】语言新特性:集合
- 本地数据库 sqlite3 编译和使用
猜你喜欢

Chrome 里的小恐龙游戏是怎么做出来的?

GM8775C规格书,MIPI转LVDS,MIPI转双路LVDS分享

HDMI转MIPI CSI东芝转换芯片-TC358743XBG/TC358749XBG

【nRF24L01 connects with Arduino to realize wireless communication】

IDEA2021.2安装与配置(持续更新)

Personal image bed construction based on Alibaba Cloud OSS+PicGo

振芯科技GM8285C:功能TTL转LVDS芯片简介

Basic IO (on): file management and descriptors

vector的使用和模拟实现:

将ORCAD原理图导入allegro中进行PCB设计
随机推荐
云服务器web项目部署详解
发布全新的配置格式 - AT
MOS管开关原理及应用详解
分割回文串 DP+回溯 (LeetCode-131)
为什么D类音频功放可以免输出滤波器
【LeetCode】求和
【Connect the heart rate sensor to Arduino to read the heart rate data】
AD8361检波器
本地数据库 sqlite3 编译和使用
WebApp 在线编程成趋势:如何在 iPad、Matepad 上编程?
2020 - AAAI - 图像修复 Image Inpainting论文导读 -《Region Normalization for Image Inpainting》
AD实战篇
回溯法 & 分支限界 - 2
C语言教程 - 制作单位转换器
Basic IO (on): file management and descriptors
判断子序列 —— LeetCode-392
【plang 1.4.4】编写贪吃蛇脚本
GM8775C规格书,MIPI转LVDS,MIPI转双路LVDS分享
进程(中):进程状态、进程地址空间
vector的使用和模拟实现: