作者: 负雪明烛
id: fuxuemingzhu
个人公众号:负雪明烛
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode-cn.com/problems/copy-list-with-random-pointer/

题目描述

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

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

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

返回复制链表的头节点。

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

  • val:一个表示 Node.val 的整数。
  • random_index:随机指针指向的节点索引(范围从 0n-1);如果不指向任何节点,则为 null

你的代码 接受原链表的头节点 head 作为传入参数。

示例 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。

提示:

  • 0 <= n <= 1000
  • -10000 <= Node.val <= 10000
  • Node.random 为空(null)或指向链表中的节点。

题目大意

复制一个复杂链表,这个复杂链表是指出了值和next指针外,还有一个random指针可能指向任何位置的链表节点或空。

解题方法

这个题是剑指Offer的“面试题26:复杂链表的复制”原题。书上的做法是在原先的每个节点之后进行复制了一个节点,从而构成了一个二倍长度的单链表,然后再修改random指针。这样做的好处是没有使用额外空间,但是缺点是做法比较麻烦。

一个更简洁的做法是使用 HashMap,在这个 HashMap 里,记录了 老链表的每个节点 和 新链表的每个节点的 对应关系。

第一步,先构造了一个纯next的链表;
第二部,对链表再次循环,修改每个节点的 random 的指针了。

Python 代码如下:

"""
# Definition for a Node.
class Node(object):
def __init__(self, val, next, random):
self.val = val
self.next = next
self.random = random
"""
class Solution(object):
def copyRandomList(self, head):
"""
:type head: Node
:rtype: Node
"""
nodeDict = dict()
dummy = Node(0, None, None)
nodeDict[head] = dummy
newHead, pointer = dummy, head
while pointer:
node = Node(pointer.val, pointer.next, None)
nodeDict[pointer] = node
newHead.next = node
newHead, pointer = newHead.next, pointer.next
pointer = head
while pointer:
if pointer.random:
nodeDict[pointer].random = nodeDict[pointer.random]
pointer = pointer.next
return dummy.next

C++ 代码如下:

/*
// 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;
unordered_map<Node*, Node*> copyMap;
Node* newHead = new Node(head->val);
Node* moveOld = head;
Node* moveNew = newHead;
while (moveOld) {
copyMap[moveOld] = moveNew;
moveNew->next = moveOld->next ? new Node(moveOld->next->val) : nullptr;
moveNew = moveNew->next;
moveOld = moveOld->next;
}
moveOld = head;
moveNew = newHead;
while (moveOld) {
moveNew->random = copyMap[moveOld->random];
moveNew = moveNew->next;
moveOld = moveOld->next;
}
return newHead;
}
};

日期

2018 年 6 月 23 日 —— 美好的周末要从刷题开始
2021 年 7 月 22 日 —— 最近天气一直是阴天下雨,希望天气好点

【LeetCode】138. Copy List with Random Pointer 复制带随机指针的链表 解题报告(Python)的更多相关文章

  1. 138 Copy List with Random Pointer 复制带随机指针的链表

    给出一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点.返回一个深拷贝的链表. 详见:https://leetcode.com/problems/copy-list- ...

  2. Leetcode138. Copy List with Random Pointer复制带随机指针的链表

    给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点. 要求返回这个链表的深度拷贝. 方法一: class Solution { public: RandomLis ...

  3. [LeetCode] 138. Copy List with Random Pointer 拷贝带有随机指针的链表

    A linked list is given such that each node contains an additional random pointer which could point t ...

  4. Java for LeetCode 138 Copy List with Random Pointer

    A linked list is given such that each node contains an additional random pointer which could point t ...

  5. [LeetCode] 138. Copy List with Random Pointer 拷贝带随机指针的链表

    A linked list is given such that each node contains an additional random pointer which could point t ...

  6. leetcode 138. Copy List with Random Pointer ----- java

    A linked list is given such that each node contains an additional random pointer which could point t ...

  7. leetcode 138. Copy List with Random Pointer复杂链表的复制

    python代码如下: # Definition for singly-linked list with a random pointer. # class RandomListNode(object ...

  8. Leetcode#138 Copy List with Random Pointer

    原题地址 非常巧妙的方法,不需要用map,只需要O(1)的额外存储空间,分为3步: 1. 先复制链表,但是这个复制比较特殊,每个新复制的节点添加在原节点的后面,相当于"加塞"2. ...

  9. [leetcode]138. Copy List with Random Pointer复制带有随机指针的链表

    public RandomListNode copyRandomList(RandomListNode head) { /* 深复制,就是不能只是复制原链表变量,而是做一个和原来链表一模一样的新链表, ...

随机推荐

  1. 苹果ios通过描述文件获取udid

    苹果ios通过描述文件获取udid 需要准备的东西 1,安装描述文件只支持https的回调地址,所以需要申请https域名 2,描述文件签名,不安装也可,只要能接受红色的字 步骤: 1,准备xml文件 ...

  2. 搭建简单的SpringCloud项目三:问题及解决

    GitHub:https://github.com/ownzyuan/test-cloud 前篇:搭建简单的SpringCloud项目一:注册中心和公共层 搭建简单的SpringCloud项目二:服务 ...

  3. vivo 敏感词匹配系统的设计与实践

    一.前言 谛听系统是vivo的内容审核平台,保障了vivo各互联网产品持续健康的发展.谛听支持审核多种内容类型,但日常主要审核的内容是文本,下图是一个完整的文本审核流程,包括名单匹配.敏感词匹配.AI ...

  4. 日常Java 2021/10/14

    Java数据结构 Java BitSet类 BitSet类创建一种特殊类型的数组来保存位值,数组大小随需要增加,BitSet(),BitSet(int size) 其中的方法 void and(Bit ...

  5. iOS 的文件操作

    直接上操作 效果:将一张图片写入文件 (图片本身已经在Assets.xcassets里面了) 1.获取当前app的沙盒路径 NSString *documentPath = NSSearchPathF ...

  6. 规范——Java后端开发规范

    Java后端开发规范 一.技术栈规约 二.命名规范 三.Java代码规范(注释规范.异常与日志.代码逻辑规范) 四.Mybatis与SQL规范 五.结果检查(单元测试及代码扫描) 六.安全规范 一.技 ...

  7. 链式栈——Java实现

    1 package struct; 2 3 //接口 4 interface ILinkStack{ 5 //栈中元素个数(栈大小) 6 int size(); 7 //取栈顶元素 8 Object ...

  8. 使用MySQL的SELECT INTO OUTFILE ,Load data file,Mysql 大量数据快速导入导出

    使用MySQL的SELECT INTO OUTFILE .Load data file LOAD DATA INFILE语句从一个文本文件中以很高的速度读入一个表中.当用户一前一后地使用SELECT ...

  9. 在Eclipse中运行OSGI工程出错的解决方案

    今天学习OSGI的过程中按照书上所述搭建好第一个helloworld插件工程,运行的过程中出现下面所示的错误: !SESSION 2014-06-09 21:04:49.038 ----------- ...

  10. 【Services】【Web】【apr】安装apr

    1. 基础: 1.1 描述:apr全称Apache Portable Runtime,常用于与ssl相关的环境支持,比如openssl,httpd,nginx,tomcat 1.2 链接: 官方网站: ...