题目描述:

  输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)。

  解题思路:

  本题有以下三种解法:

  第一种:先按照next复制,然后依次添加random指针,添加时需要定位random的位置,定位一次需要一次遍历,需要O(n^2)的复杂度。

  第二种:先按照next复制,然后用一个hashmap保存原节点和复制后节点的对应关系,则用O(n)的空间复杂度使时间复杂度降到了O(n)。

   第三种(最优方法):同样先按next复制,但是把复制后的节点放到原节点后面,则可以很容易的添加random,最后按照奇偶位置拆成两个链表,时间复杂度O(n),不需要额外空间。

  举例:

![](https://img2018.cnblogs.com/blog/1608161/201905/1608161-20190503152726651-930857210.png)
![](https://img2018.cnblogs.com/blog/1608161/201905/1608161-20190503152736226-1294586725.png)
![](https://img2018.cnblogs.com/blog/1608161/201905/1608161-20190503152744499-1216401661.png)

  编程实现(Java):

public class Solution {
public RandomListNode Clone(RandomListNode pHead){
if(pHead==null)
return null;
//(1)先按next复制,但是把复制后的节点放到对应原节点后面
CopyNodes(pHead);
//(2)依次添加random指针
addRandom(pHead);
//(3)按照奇偶位置拆成两个链表
return ReconnectNodes(pHead);
}
//先按next复制,但是把复制后的节点放到对应原节点后面
public void CopyNodes(RandomListNode pHead){
RandomListNode head=pHead;
while(head!=null){
RandomListNode temp=new RandomListNode(head.label);
temp.next=head.next; //复制一个结点,插在对应的原节点的后面
temp.random=null;
head.next=temp;
head=temp.next;
}
}
//依次添加random指针
public void addRandom(RandomListNode pHead){
RandomListNode head=pHead;
while(head!=null){
RandomListNode head_new=head.next;
if(head.random!=null)
head_new.random=head.random.next;
head=head_new.next;
}
}
//按照奇偶位置拆成两个链表
public RandomListNode ReconnectNodes(RandomListNode pHead){
if(pHead==null)
return null;
RandomListNode head=pHead;
RandomListNode pHeadClone=head.next;
RandomListNode headClone=pHeadClone;
while(head!=null){
head.next=headClone.next;
head=head.next;
if(head!=null){
headClone.next=head.next;
headClone=headClone.next;
}
}
return pHeadClone;
}
}

【剑指Offer】25、复杂链表的复制的更多相关文章

  1. 剑指Offer 25. 复杂链表的复制 (链表)

    题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否 ...

  2. [剑指Offer] 25.复杂链表的复制

    /* struct RandomListNode { int label; struct RandomListNode *next, *random; RandomListNode(int x) : ...

  3. 剑指 Offer 35. 复杂链表的复制

    剑指 Offer 35. 复杂链表的复制 Offer_35 题目详情 方法一 可以使用一个HashMap来存储旧结点和新结点的映射. 这种方法需要遍历链表两遍,因为需要首先知道映射关系才能求出next ...

  4. 【剑指Offer】复杂链表的复制 解题报告(Python)

    [剑指Offer]复杂链表的复制 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews 题 ...

  5. 《剑指offer》复杂链表的复制

    本题来自<剑指offer> 反转链表 题目: 思路: C++ Code: Python Code: 总结:

  6. 【Java】 剑指offer(35) 复杂链表的复制

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 请实现函数ComplexListNode* Clone(Compl ...

  7. Go语言实现:【剑指offer】复杂链表的复制

    该题目来源于牛客网<剑指offer>专题. 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.( ...

  8. 剑指offer——35复杂链表的复制

    这题很是巧妙. 突破了常规思维. 竟然可以把传入进来的链表和复制的链表链在一起.然后再算出slibling指针.最后在分离. 直接把空间复杂度变为O(1)了. 很巧妙,很实用. 题目: 请实现函数Co ...

  9. 剑指OFFER之复杂链表的复制(九度OJ1524)

    题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点). 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一 ...

  10. 剑指offer:复杂链表的复制

    题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用, ...

随机推荐

  1. [csdn markdown]使用摘记一源码高亮及图片上传和链接

    本文主要内容是体验csdn markdown的代码块高亮显示和图片链接及上传. 图片上传 上边这是标题行.仅仅须要使用一个#就能够表示.几个表示是几级标题 图片上传 本地图片上传控件 本地图片上传方式 ...

  2. USB设备驱动之设备初始化(设备枚举)

    USB设备从接入HUB到正常工作之前.都属于设备枚举阶段.所谓设备枚举.就是让host控制器认识USB设备,并为其准备资源.建立好主机与设备间的数据传递机制. 该阶段的工作,是USB通信协议规定的,所 ...

  3. Lucene5学习之使用MMSeg4j分词器

      分类:程序语言|标签:C|日期: 2015-05-01 02:00:24 MMSeg4j是一款中文分词器,详细介绍如下: 1.mmseg4j 用 Chih-Hao Tsai 的 MMSeg 算法( ...

  4. Deep Learning Toolboxs

    一些好用的 Deep learning toolboxs DeepLearningToolbox MATLAB实现,能够使用CPU或GPU.GPU运算用gpumat实现.改动内核代码很方便 支持主要的 ...

  5. Entity Framework Utility .ttinclude File

    https://msdn.microsoft.com/en-us/library/ff477603(v=vs.100).aspx This topic provides an overview of ...

  6. Oracle Instant Client 安装配置

    一.下载 下载地址:http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html 这是Ora ...

  7. 有关于dict(字典)的特性与操作方法

    有关于dict(字典)的特性与操作方法 1.字典的特性 语法: dic = {key1 : value1,key2 : value2,key3 : value3............} 注:字典中k ...

  8. Java并发基础知识点详解

    1.synchronized与Lock区别 父类有synchtonized,子类调用父类的同步方法,是没办法同步的,因为synchronized不是修饰符,不会被继承下来. synchronized ...

  9. ubuntu 软件桌面图标创建

    sublime text 的安装目录是:/usr/local/sublimetext $cd 桌面 $vim Sublime\ Text.desktop 添加如下内容: [Desktop Entry] ...

  10. 海量数据统计topK

    有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M.返回频数最高的100个词. 思路: 把这1G的数据一次性全部读入内存是不可能了,可以每次读一行,然后将该词存到 ...