题目:

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. 2017最新最稳定的合买彩票源码asp+sql2008 新增PK式彩种+全新界面

    下载地址: http://115.238.250.104:81/cnzz_code/2016-05/04/klcphm_v2016.rar 网站后台管理系统:新闻资讯系统 用户管理系统用户登录日志彩种 ...

  2. OpenCV探索之路(三):滤波操作

    滤波处理分为两大类:线性滤波和非线性滤波.OpenCV里有这些滤波的函数,使用起来非常方便,现在简单介绍其使用方法. 线性滤波:方框滤波.均值滤波.高斯滤波 方框滤波 #include<open ...

  3. MyBatis之级联——一对一关系

    在学数据库概论的时候会听到这么几个词:数据库的关系分为一对一.一对多.多对多.对于在学校里学的知识已经忘得差不多了,在这里简单的提一下数据库的关系.此篇是介绍MyBatis是如何实现数据库中一对一关系 ...

  4. UVa1025 (DAG上的dp)

    这是紫书上的第一个dp哈. 1.状态定义:dp[i][j]---->到时刻i的时候(出发的时候时刻为0,约定时间为时刻time),从j号车站开往N号车站,在车站等待的最少的时间. 2.这个人当前 ...

  5. SPRING AOP ....0 can't find referenced pointcut

    下载最新的aspectjweaver就可以了,因为JDK的版本的问题不兼容. //织入点语法 @Pointcut("execution(public * com.frank.dao..*.* ...

  6. 【转】典型的JavaScript面试题

    问题1: 作用域(Scope) (function() { "use strict"; var a = b = 5; })(); console.log(b); 控制台(conso ...

  7. 关于Java解压文件的一些坑及经验分享(MALFORMED异常)

    文章也已经同步到我的csdn博客: http://blog.csdn.net/u012881584/article/details/72615481 关于Java解压文件的一些坑及经验分享 就在本周, ...

  8. UICollectionView左对齐流水布局、右对齐流水布局

    在平时使用的app中会经常碰到一些规格选择,筛选,标签等页面,这些页面的布局展示通常是左对齐流水布局.实现类似这样的左对齐流水布局有多种方式,如果选项少的话可以直接用UIButton实现.现在我们有一 ...

  9. A Bayesian election prediction, implemented with R and Stan

    If the media coverage is anything to go by, people are desperate to know who will win the US electio ...

  10. 用R语言做数据清理(详细教程)

    数据的清理 如同列夫托尔斯泰所说的那样:“幸福的家庭都是相似的,不幸的家庭各有各的不幸”,糟糕的恶心的数据各有各的糟糕之处,好的数据集都是相似的.一份好的,干净而整洁的数据至少包括以下几个要素: 1. ...