题目

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.

分析

实现一个链表的深拷贝,返回拷贝后的新链表。

若是普通链表,逐个拷贝原始链表节点并连接即可,只需O(n)的时间复杂度;但是此题特殊的是,每个节点都有一个random域可以指向该链表中的任何一个节点,所以直接复制无法处理random域,因为其指向的节点很有可能还没有创建出来。

有两种方法处理:

方法一:暴力解决,首先不处理random域,将原始链表复制一份,然后遍历每个原始链表节点,查找其random域,将新链表的对应节点链接,该方法需要O(n^2)的时间复杂度,给出的结果是TLE。

方法二:充分利用原始链表的信息,不用保存原始链表的映射关系,构建新节点时,指针做如下变化,即把新节点插入到相应的旧节点后面(参考):



同理分两步

1、构建新节点random指针:

new1->random = old1->random->next, new2-random = NULL,
new3-random = NULL, new4->random = old4->random->next

2、恢复原始链表以及构建新链表:

old1->next = old1->next->next,  new1->next = new1->next->next

该算法时间复杂度O(N),空间复杂度O(1)

AC代码

class Solution {
public:
//方法一:直接复制,再修改random指针
RandomListNode *copyRandomList1(RandomListNode *head) {
if (!head)
return NULL; RandomListNode *ret = new RandomListNode(head->label), *q = ret;
RandomListNode *p = head->next;
while (p)
{
RandomListNode *tmp = new RandomListNode(p->label);
q->next = tmp;
q = q->next; p = p->next;
}//while
q->next = NULL; //处理原始链表的random指针
p = head, q = ret;
RandomListNode *idx1 = head, *idx2 = ret;
while (p)
{
if (p->random == NULL)
q->random = NULL;
else{
idx1 = head;
idx2 = ret;
while (p->random->label != idx1->label)
{
idx1 = idx1->next;
idx2 = idx2->next;
}//while
q->random = idx2;
}//else
p = p->next;
q = q->next;
}//while
return ret;
} //方法二:充分利用原始链表信息,在每个节点后复制添加
RandomListNode *copyRandomList(RandomListNode *head) {
if (!head)
return NULL; //首先,复制原始的节点,连接自身后面
RandomListNode *p = head;
while (p)
{
RandomListNode *tmp = new RandomListNode(p->label);
//保存后续节点
RandomListNode *r = p->next; tmp->next = r;
p->next = tmp; p = r;
}//while //然后,将添加的节点random 链接到原始节点random的下一个位置
p = head;
while (p)
{
RandomListNode *q = p->next;
if (p->random == NULL)
q->random = NULL;
else{
q->random = p->random->next;
}//else
//处理下一个原始节点
p = q->next;
}//while //最后,恢复原始链表,得到新链表
RandomListNode *ret = head->next; p = head;
RandomListNode *q = head->next;
while (q->next)
{
p->next = q->next;
p = q;
if (q->next)
q = q->next;
}
p->next = NULL;
q->next = NULL;
return ret;
} };

GitHub测试程序源码

LeetCode(138) Copy List with Random Pointer的更多相关文章

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

  2. 【LeetCode练习题】Copy List with Random Pointer

    Copy List with Random Pointer A linked list is given such that each node contains an additional rand ...

  3. [Leetcode Week17]Copy List with Random Pointer

    Copy List with Random Pointer 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/copy-list-with-random- ...

  4. LeetCode(275)H-Index II

    题目 Follow up for H-Index: What if the citations array is sorted in ascending order? Could you optimi ...

  5. LeetCode(220) Contains Duplicate III

    题目 Given an array of integers, find out whether there are two distinct indices i and j in the array ...

  6. LeetCode(154) Find Minimum in Rotated Sorted Array II

    题目 Follow up for "Find Minimum in Rotated Sorted Array": What if duplicates are allowed? W ...

  7. LeetCode(122) Best Time to Buy and Sell Stock II

    题目 Say you have an array for which the ith element is the price of a given stock on day i. Design an ...

  8. LeetCode(116) Populating Next Right Pointers in Each Node

    题目 Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode * ...

  9. LeetCode(113) Path Sum II

    题目 Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given ...

随机推荐

  1. GDPR(Cookie处理)

    GDPR(Cookie处理) https://www.cnblogs.com/GuZhenYin/p/9154447.html 前言 时间一晃 ASP.NET Core已经迭代到2.1版本了. 迫不及 ...

  2. Middleware-请求管道的构成

    Middleware-请求管道的构成 在 ASP.NET 中,我们知道,它有一个面向切面的请求管道,有19个主要的事件构成,能够让我们进行灵活的扩展.通常是在 web.config 中通过注册 Htt ...

  3. CodeForces 731C C - Socks 并查集

    Description Arseniy is already grown-up and independent. His mother decided to leave him alone for m ...

  4. vs2012 support BI

    Microsoft SQL Server Data Tools - Business Intelligence for Visual Studio 2012 http://www.microsoft. ...

  5. Spark Mllib里的本地向量集(密集型数据集和稀疏型数据集概念、构成)(图文详解)

    不多说,直接上干货! Local  vector : 本地向量集 由两类构成:稀疏型数据集(spares)和密集型数据集(dense) (1).密集型数据集 例如一个向量数据(9,5,2,7),可以设 ...

  6. Spark Mllib里如何记录开始训练时间、完成训练时间、所需训练时间(图文详解)

    不多说,直接上干货! 具体,见 Hadoop+Spark大数据巨量分析与机器学习整合开发实战的第16章 朴素贝叶斯二元分类算法来预测分类StumbleUpon数据集

  7. Centos安装TensorFlow和Keras

    安装命令如下: curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py python get-pip.py pip install tensor ...

  8. RabbitMQ使用教程(二)RabbitMQ用户管理,角色管理及权限设置

    上一篇博客 RabbitMQ使用教程(一)RabbitMQ环境安装配置及Hello World示例 中,我们成功的安装好了RabbitMQ环境,并通过一个Java客户端示例了解了用生产者来发布消息,用 ...

  9. [代码修订版] Python 踩坑之旅 [进程篇其四] 踩透 uid euid suid gid egid sgid的坑坑洼洼

    目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4 技术关键字 1.5 坑后思考 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: 2.7.14 代码示例: 公 ...

  10. mysql 存储过程变量及循环的使用

    1.用游标循环 BEGIN -- 定义变量 -- 定义done DECLARE done INT; -- 定义 ammeter_id_bl DECLARE ammeter_id_bl DOUBLE; ...