题目:

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.

提示:

此题有两种方法,一种是按照原链表next的顺序依次创建节点,并处理好新链表的next指针,同时把原节点与新节点的对应关系保存到一个hash_map中,然后第二次循环将random指针处理好。这种方法的时间复杂度是O(n),空间复杂度也是O(n)。

第二种方法则是在原链表的每个节点之后插入一个新的节点,这样原节点与新节点的对应关系就已经明确了,因此不需要用hash_map保存,但是需要第三次循环将整个链表拆分成两个。这种方法的时间复杂度是O(n),空间复杂度是O(1)。

但是利用hash_map的方法具有其他的优点,如果在循环中加入一个判断,就可以检测出链表中是否有循环;而第二种方法则不行,会陷入死循环。

代码:

使用hash_map的方法:

/**
* Definition for singly-linked list with a random pointer.
* struct RandomListNode {
* int label;
* RandomListNode *next, *random;
* RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
* };
*/
class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head) {
if (!head) return NULL;
unordered_map<RandomListNode*, RandomListNode*> mp;
// 创建一个新的链表头
RandomListNode *new_head = new RandomListNode(head->label);
// node1负责指向原链表,node2负责指向新链表
RandomListNode *node1 = head, *node2 = new_head;
/**
* 按照原链表的结构不断创建新的节点,并维护好next指针,将node1与node2的对应关系保存到hash_map中,
* 以备后面维护random指针的时候,可以通过node1找到对应的node2。
*/
while (node1->next != NULL) {
mp[node1] = node2;
node1 = node1->next;
node2->next = new RandomListNode(node1->label);
node2 = node2->next;
}
// 将两个链表的尾巴的对应关系也保存好
mp[node1] = node2; // 继续从头开始处理random指针
node1 = head;
node2 = new_head;
while (node1->next != NULL) {
node2->random = mp[node1->random];
node1 = node1->next;
node2 = node2->next;
}
// 把尾巴的random指针也处理好
node2->random = mp[node1->random];
return new_head;
}
};

不使用hash_map的方法:

/**
* Definition for singly-linked list with a random pointer.
* struct RandomListNode {
* int label;
* RandomListNode *next, *random;
* RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
* };
*/
class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head) {
/**
* 假设:l1代表原链表中的节点;l2代表新链表中的节点
*/
RandomListNode *new_head, *l1, *l2;
if (head == NULL) return NULL; /**
* 第一步:在每一个l1后面创建一个l2,并让l1指向l2,l2指向下一个l1;
*/
for (l1 = head; l1 != NULL; l1 = l1->next->next) {
l2 = new RandomListNode(l1->label);
l2->next = l1->next;
l1->next = l2;
} /**
* 第二步:给l2的random赋值,l1的random的next指向的就是l2的random的目标;
*/
new_head = head->next;
for (l1 = head; l1 != NULL; l1 = l1->next->next) {
if (l1->random != NULL) l1->next->random = l1->random->next;
} /**
* 第三步:需要将整个链表拆成两个链表,具体做法是让l1的next指向后面的后面;
* l2的next也指向后面的后面。
*/
for (l1 = head; l1 != NULL; l1 = l1->next) {
l2 = l1->next;
l1->next = l2->next;
if (l2->next != NULL) l2->next = l2->next->next;
}
return new_head;
}
};

【LeetCode】138. Copy List with Random Pointer的更多相关文章

  1. 【LeetCode】138. Copy List with Random Pointer 复制带随机指针的链表 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人公众号:负雪明烛 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https:/ ...

  2. 【原创】leetCodeOj --- Copy List with Random Pointer 解题报告

    题目地址: https://oj.leetcode.com/problems/copy-list-with-random-pointer/ 题目内容: A linked list is given s ...

  3. 【Lintcode】105.Copy List with Random Pointer

    题目: A linked list is given such that each node contains an additional random pointer which could poi ...

  4. 133. Clone Graph 138. Copy List with Random Pointer 拷贝图和链表

    133. Clone Graph Clone an undirected graph. Each node in the graph contains a label and a list of it ...

  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. 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 ...

  7. [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 ...

  8. 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 ...

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

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

随机推荐

  1. 一分钟应对勒索病毒WannaCry

    一.WannaCry 勒索病毒 勒索病毒WannaCry肆虐全球,利用Windows操作系统漏洞,因链式反应迅猛自动传播,校园电脑.个人电脑.政府机关都是重灾区.中毒电脑所有文档被加密,将被勒索高达3 ...

  2. TCP协议简介

    1.TCP协议的特点 TCP是面向连接的运输层协议 每一条TCP连接只能有两个端点.TCP只能进行点对点通信 TCP提供可靠交付的服务.通过TCP连接传输的数据,无差错.不丢失.不重复.并且按序到达 ...

  3. jqPaginator 项目中做分页的应用技巧

    最近做后台管理系统,分页用到的不少,项目中其实已经有分页功能的组件但是不够高度自定义,于是就找到了 jqPaginator 高度自定义的Html结构 初始化引用如下: $("#paginat ...

  4. 自学JS

    通过慕课网自学JS,敲了好多代码,好像没什么卵用,附上代码,再接再厉吧! //属性getter setter方法var man = {name : 'wsy', weibo : '@wsy', get ...

  5. js导出CSV

    <html> <head> <meta http-equiv="content-type" content="text/html; char ...

  6. 【JAVAWEB学习笔记】20_增删改查

    今天主要是利用三层架构操作数据库进行增删查改操作. 主要是编写代码为主. 附图: 前台和后台 商品的展示 修改商品

  7. 【JAVAWEB学习笔记】11_XML&反射

    解析XML总结(SAX.Pull.Dom三种方式) 图一 XML的解析方式 图二 XML的Schema的约束 反射的简单介绍: 反射 1.什么是反射技术? 动态获取指定类以及类中的内容(成员),并运行 ...

  8. 高效工作的秘诀——Doit.im使用总结报告

    从上次购买doit.im pro账户到现在已经快一年了,从摸索到现在的熟悉,目前这款软件已经成为我工作生活中最为重要的效率工具,在此之前也用过很多软件进行时间管理,综合起来评价,doit应该算是最棒的 ...

  9. 谈一谈Java8的函数式编程 (三) --几道关于流的练习题

    为什么要有练习题?    所谓学而不思则罔,思而不学则殆,在系列第一篇就表明我认为写博客,既是分享,也是自己的巩固,我深信"纸上得来终觉浅,绝知此事要躬行"的道理,因此之后的几篇博 ...

  10. webpack 初识

    Webpack介绍 webpack 官网 http://webpack.github.io/docs/ webpack 中文地址:https://doc.webpack-china.org/ webp ...