题目:

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. Oracle数据库悲观锁与乐观锁详解

    数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁.什么叫悲观锁呢,悲观锁顾名思义,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住.而乐 ...

  2. rsyslog管理分布式日志

    [TOC] 背景 有一个4台机器的分布式服务,不多不少,上每台机器上查看日志比较麻烦,用Flume,Logstash.ElasticSearch.Kibana等分布式日志管理系统又显得大材小用,所以想 ...

  3. xpo-4大类

      Xpo (XPBaseObject.XPLiteObject.XPCustomObject.XPObject) 类名 延后删除 是否乐观锁定 提供OID字段 XPBaseObject 不支持 支持 ...

  4. 基于java:读写一个英文的txt文件,记录单词个数,并输出十个出现最多的单词及出现的个数;

    import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; class W ...

  5. React学习小结(二)

    一.组件的嵌套 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t ...

  6. 容器扩展属性 IExtenderProvider 实现WinForm通用数据验证组件

    大家对如下的Tip组件使用应该不陌生,要想让窗体上的控件使用ToolTip功能,只需要拖动一个ToolTip组件到窗口,所有的控件就可以使用该功能,做信息提示. 本博文要记录的,就是通过容器扩展属性 ...

  7. PHP实现Collection数据集类及其原理

    本文目录 : Collection源码 讲解与例子 ArrayAccess的使用 JsonSerializable的使用 Countable的使用 IteratorAggregate.ArrayIte ...

  8. python-广度优先搜索

    广度优先搜索 下面我们来来BFS算法策略: 比如:我们要从双子峰---->金门大桥,最短路径如何? 我们利用广度优先搜索来一步步求解,注意广度优先搜索在于的关键在于"广",也 ...

  9. Java web中常见编码乱码问题(一)

    最近在看Java web中中文编码问题,特此记录下. 本文将会介绍常见编码方式和Java web中遇到中文乱码问题的常见解决方法: 一.常见编码方式: 1.ASCII 码 众所周知,这是最简单的编码. ...

  10. 【MyBatis源码分析】insert方法、update方法、delete方法处理流程(下篇)

    Configuration的newStatementHandler分析 SimpleExecutor的doUpdate方法上文有分析过: public int doUpdate(MappedState ...