如图1所示,有一条单链表,其节点除了有next指针外,还有一个random指针。random指针可指向单链表中的任意节点,包括它自身。random指针一旦指定,便不再更改。请设计算法,复制此单链表,并给出时间复杂度。

  图1 带有random指针的单链表

解法1. 时间复杂度为O(n*n)

先按next指针,将链表复制一份。使用p1指向原链表的头节点,p2指向p1指向的节点的random节点,p3指向p1的next节点,cnt记录p3移动的步数,p4指向新链表的头节点。对比p3和p2的指向:如果p2和p3地址不一致,则p3移向本节点的next节点,并记录移动的频数加1。如此反复,直到p3指向的地址与p2指向的地址一致。使用p5指向p4的next节点,再向后移动cnt次,得到p4指向的节点的random指针应该指向的位置。将p1和p4同时移向各自的next。如此反复。

解法2. 时间复杂度为O(2n)

想要降低时间复杂度,就需要增加空间复杂度,拿空间换时间。解法1的时间复杂度高的原因为查找新链表中random指针的指向,哈希表可解决查找慢的问题。

可建立一个hash表,使用原链表的节点的地址的hash值作下标,使用新链表对应的地址作value。这样遍历原链表一遍后,节点的random指向为NULL的新链表可建立起来,并且建立了一张hash表。再遍历一遍,p1指向原链表中某节点,p2指向新链表中对应的某节点。将p1的random指针指向的地址做hash后,可得到hash表中新链表对应的地址值。再将p2的random指针指向该地址即可。如此反复。

解法3. 时间复杂度为O(2n),空间复杂度为O(1)

解法2所花费的空间有些大了,解决法通破坏原链表的方法,代替了hash表,解决了查找random指针指向的问题。虽然原链表被破坏了,但可被恢复到原样。

首先遍历原链表,同时建立新链表。将新链表的random指针指向原链表对应节点的next节点,将原链表的next指针指向新链表的对应节点。

再遍历一次原链表和新链表,p1指向原链表的某节点,p2指向新链表的对应节点。从p1可知random指向的节点,从此节点的next指针可知新链表的对应节点,使用p3指针指向该节点。将p1的next指向p2的random指针指向的节点,再将p2的random指针指向p3。p1和p2均指向自己的next节点。如此反复。

解法3的示意图如下:

复制带有random指针的单链表的更多相关文章

  1. 40深入理解C指针之---指针与单链表

    一.指针与单链表 1.定义:通过使用指针将节点(结点)链接起来成为链表 2.节点(结点): 1).数据域:主要用来存储数据,可以基本数据类型,也可以是构造数据类型: 2).指针域:主要用来当前节点(结 ...

  2. [leetcode]138. Copy List with Random Pointer复制带有随机指针的链表

    public RandomListNode copyRandomList(RandomListNode head) { /* 深复制,就是不能只是复制原链表变量,而是做一个和原来链表一模一样的新链表, ...

  3. LeetCode——Copy List with Random Pointer(带random引用的单链表深拷贝)

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

  4. 复制一个带random指针的链表

    一个单链表,其中除了next指针外,还有一个random指针,指向链表中的任意某个元素.如何复制这样一个链表呢? 通过next来复制一条链是很容易的,问题的难点在于如何恰当地设置新链表中的random ...

  5. 【链表问题】打卡9:将单链表的每K个节点之间逆序

    前言 以专题的形式更新刷题贴,欢迎跟我一起学习刷题,相信我,你的坚持,绝对会有意想不到的收获.每道题会提供简单的解答,如果你有更优雅的做法,欢迎提供指点,谢谢. 注:如果代码排版出现了问题麻烦通知我下 ...

  6. 数据结构 - 动态单链表的实行(C语言)

    动态单链表的实现 1 单链表存储结构代码描述 若链表没有头结点,则头指针是指向第一个结点的指针. 若链表有头结点,则头指针是指向头结点的指针. 空链表的示意图: 带有头结点的单链表: 不带头结点的单链 ...

  7. 《数据结构》2.3单链表(single linked list)

    //单链表节点的定义 typedef struct node { datatype data; struct node *next; }LNode,*LinkList; //LNode是节点类型,Li ...

  8. 数组、单链表和双链表介绍 以及 双向链表的C/C++/Java实现

    概要 线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列.本章先介绍线性表的几个基本组成部分:数组.单向链表.双向链表:随后给出双向链表的C.C++和Java三种语言的实现. ...

  9. 删除单链表倒数第n个节点

    基本问题 如何删除单链表中的倒数第n个节点? 常规解法 先遍历一遍单链表,计算出单链表的长度,然后,从单链表头部删除指定的节点. 代码实现 /** * * Description: 删除单链表倒数第n ...

随机推荐

  1. Struts2国际化文件乱码解决

    方法1:使用native2ascii进行编码转换 代码如下: native2ascii -encoding UTF-8 GlobalMessages.properties NewGlobalMessa ...

  2. Django提供后台接口的跨域问题

    --> Django跨域 当使用Django仅用来开发后端接口,为前端提供JSON数据的时候,不可避免的要接受前端的POST请求.虽然Django以其强大易用的特定使用很广泛,但在跨域问题上却让 ...

  3. 嵌入式Linux系统运行流程图

    /************************************************************************ * 嵌入式Linux系统运行流程图 * 说明: * ...

  4. apache开源项目--Mahout

    Apache Mahout 是 Apache Software Foundation (ASF) 开发的一个全新的开源项目,其主要目标是创建一些可伸缩的机器学习算法,供开发人员在 Apache 在许可 ...

  5. iOS--跳转到APPstore评分

    本代码适用于iOS7之后的版本: NSString *str = [NSString stringWithFormat:@"itms-apps://itunes.apple.com/app/ ...

  6. oracle 问题若干 提醒注意

    1.Powerdesigner 里生成sql,在oracle中运行时报错:ORA-00907: 缺失右括号 解决:这样的问题很多时候是因为用了不正确的数据类型造成的.比如写作nvarchar(n),但 ...

  7. WPF 中资源路径的问题

    WPF 中资源路径的问题 1. 引用当前工程的资源(注意xxxx.png的build action 应设置为Resource 或Embedded Resource) <ImageBrush Im ...

  8. lightoj 1019

    裸的最短路 dijkstra #include<cstdio> #include<string> #include<cstring> #include<ios ...

  9. win7(64位)+IE8+QC9.0

    环境win7(64位)+IE8+QC9.0出现的问题IE8访问QC9.0有时访问登录显示正常,但是有时访问QC页面无法显示正常,然后在ie8中安全中设置“启用内存保护帮助减少联机攻击*”也无法找到该项 ...

  10. HDU-4675 GCD of Sequence 数学

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4675 题意:给一个大小为N的数列a[i],然后一个数M以及一个数K,要你求得一个数列b[i],其中b[ ...