作者: 负雪明烛
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. phpexcel 另存Excel文件方式

    $w = new PHPExcel_Writer_Excel5($e); $dir = 'path/title.xls'; $w->save($dir);

  2. IDEA+maven+javafx(java 1.8)入坑记录

    序 好久没写博客了,主要是因为懒,写博客真的是个难坚持的事.但今天登上来看了看,之前记录ctf写的wp竟然点击量这么多了,突然让我有了继续写下去的动力. 这段时间遇到了好多事,中间也有想过写几篇文章记 ...

  3. 01 Windows安装C语言环境

    安装C语言运行环境 双击打开安装文件,进行安装 配置环境变量 将: C:\MinGW\bin;添加到Path变量里面. 验证环境变量是否成功 gcc –v 出现如下图所示,证明安装成功

  4. 振鹏学习Java的第二天!

    一.今日收获 1.了解了eclipse的具体使用方法. 2.学习了Java程序设计完全手册的第一章内容,明白了相关知识. 3.通过看哔哩哔哩的java的教程视频了解了Dos命令及java的变量和常量. ...

  5. MapReduce08 数据清洗(ETL)和压缩

    目录 数据清洗(ETL) ETL清洗案例 需求 需求分析 实现代码 编写WebLogMapper类 编写WebLogDriver类 打包到集群运行 压缩 概念 MR支持的压缩编码 压缩算法对比 压缩性 ...

  6. Go Robot

    1 <html> 2 <meta http-equiv="Content-Type" content="text/html; charset=utf-8 ...

  7. SpringMVC(1):SpringMVC入门

    一,MVC 概述 MVC:模型,视图,控制器,是一种软件设计规范,本质是将业务逻辑,数据,显示,分离的方式来编写代码:前后端分离 Model:数据模型,提供要展示的数据,一般我们都会把这两个分离开来. ...

  8. springmvc中的异常处理方法

    //1.自定义异常处理类       2.编写异常处理器    3.配置异常处理器 package com.hope.exception;/** * 异常处理类 * @author newcityma ...

  9. 【简】题解 P5283 [十二省联考2019]异或粽子

    传送门:P5283 [十二省联考2019]异或粽子 题目大意: 给一个长度为n的数列,找到异或和为前k大的区间,并求出这些区间的异或和的代数和. QWQ: 考试时想到了前缀异或 想到了对每个数按二进制 ...

  10. Identity Server 4 从入门到落地(十二)—— 使用Nginx集成认证服务

    前面的部分: Identity Server 4 从入门到落地(一)-- 从IdentityServer4.Admin开始 Identity Server 4 从入门到落地(二)-- 理解授权码模式 ...