问题:

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.

结点的定义如下:

/** 
* Definition for singly-linked list with a random pointer. 
* class RandomListNode { 
*     int label; 
*     RandomListNode next, random; 
*     RandomListNode(int x) { this.label = x; } 
* }; 
*/

分析:

原来的链表的结构如下图所示:

注意一点,random的指针可以指向后面的结点,也可以指向前面的结点。

这里提供两种解法:

方法1:用hash表存储结点信息,时间O(2n),空间O(n)

第一次遍历原链表,并构建random为null的新链表,于此同时在hash表中存储原结点和新结点的地址信息,原结点地址为key,新结点地址为value,即map<原结点地址,新结点地址>

第二次遍历原链表,对于random不为空的结点,可以根据random的值,在hash表中找到random指向的节点对应的新结点的地址,再以此给新结点random赋值即可。

方法2:先改变原链表的结构,在恢复,时间O(2n),空间O(1)

这个方法需要3次遍历,

第一次,构建新链表的结点,random为null,并且用原来链表节点的next指向对应的新结点,新结点的next指向原链表的下一个结点,如图所示:

第二次,给新节点的random赋值,

p = head;
while(p!=null){
if(p.random != null){
p.next.random = p.random.next;
}
p = p.next.next;
}

第三次,恢复原链表和新链表的链表结构。

head2 = head.next;
p = head;
while(p!=null){
p2 = p.next;
p.next = p2.next;
if (p2.next != null) p2.next = p2.next.next;
p = p.next;
}

方法2的完整代码:

public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
if(head == null)return null;
RandomListNode head2,p2,p = head;
while(p!=null){
RandomListNode n = new RandomListNode(p.label);
n.next = p.next;
p.next = n;
p = n.next;
}
p = head;
while(p!=null){
if(p.random != null){
p.next.random = p.random.next;
}
p = p.next.next;
} head2 = head.next;
p = head;
while(p!=null){
p2 = p.next;
p.next = p2.next;
if (p2.next != null) p2.next = p2.next.next;
p = p.next;
}
return head2;
}
}

单链表(带random指针)深拷贝(Copy List with Random Pointer)的更多相关文章

  1. 已知单链表的数据元素为整型数且递增有序,L为单链表的哨兵指针。编写算法将表中值大于X小于Y的所有结点的顺序逆置。(C语言)

    对此题目的完整示例可直接运行代码如下: #include <stdio.h> #include <stdlib.h> typedef struct LNode{ int dat ...

  2. Python与数据结构[0] -> 链表/LinkedList[0] -> 单链表与带表头单链表的 Python 实现

    单链表 / Linked List 目录 单链表 带表头单链表 链表是一种基本的线性数据结构,在C语言中,这种数据结构通过指针实现,由于存储空间不要求连续性,因此插入和删除操作将变得十分快速.下面将利 ...

  3. 数据结构算法C语言实现(二)---2.3线性表的链式表示和实现之单链表

    一.简述 [暂无] 二.头文件 #ifndef _2_3_part1_H_ #define _2_3_part1_H_ //2_3_part1.h /** author:zhaoyu email:zh ...

  4. 线性表->链式存储->线形链表(单链表)

    文字描述: 为了表示前后两个数据元素的逻辑关系,对于每个数据元素,除了存储其本身的信息之外(数据域),还需存储一个指示其直接后继的信息(即直接后继的存储位置,指针域). 示意图: 算法分析: 在单链表 ...

  5. C语言版本:单链表的实现(优化版本)

    未优化版本:http://www.cnblogs.com/duwenxing/p/7569376.html slist.h #ifndef __SLIST_H__ #define __SLIST_H_ ...

  6. 动态单链表的传统存储方式和10种常见操作-C语言实现

    顺序线性表的优点:方便存取(随机的),特点是物理位置和逻辑为主都是连续的(相邻).但是也有不足,比如:前面的插入和删除算法,需要移动大量元素,浪费时间,那么链式线性表 (简称链表) 就能解决这个问题. ...

  7. 数据结构C语言实现系列——线性表(线性表链接存储(单链表))

    #include <stdio.h>#include <stdlib.h>#define NN 12#define MM 20typedef int elemType ;/** ...

  8. 63.如何对单链表进行快排?和数组快排的分析与对比[quicksort of array and linked list]

    [本文链接] http://www.cnblogs.com/hellogiser/p/quick-sort-of-array-and-linked-list.html [题目] 单链表的特点是:单向. ...

  9. C语言单链表实现19个功能完全详解

    谢谢Lee.Kevin分享了这篇文章 最近在复习数据结构,想把数据结构里面涉及的都自己实现一下,完全是用C语言实现的. 自己编写的不是很好,大家可以参考,有错误希望帮忙指正,现在正处于编写阶段,一共将 ...

随机推荐

  1. linux CentOS 安装rz和sz命令 lrzsz 实现windows和linux之间的文件上传 下载

    https://blog.nbhao.org/1902.html https://bbs.csdn.net/topics/391989523 https://www.cnblogs.com/zhoul ...

  2. eclipse 和 Myeclipse中Maven Web项目出现小红叉的 详细解决方法

    在我们创建maven项目是常会出现小红叉,如图: 解决办法: 1.可以 点击鼠标右键  maven--->update project.一般可以解决. 2.查看 window---->sh ...

  3. 内存泄漏检测工具VLD在VS2010中的使用举例

    Visual LeakDetector(VLD)是一款用于Visual C++的免费的内存泄露检测工具.它的特点有:(1).它是免费开源的,采用LGPL协议:(2).它可以得到内存泄露点的调用堆栈,可 ...

  4. javascript如何判断是手机还是电脑访问本网页

    var system ={}; var p = navigator.platform; system.win = p.indexOf("Win") == 0; system.mac ...

  5. 通过日志查看Web Api详细运行过程

    1. 通过Nuget安装System.Web.Http.Tracing. 2. 通过HttpConfiguration,注册SystemDiagnosticsTraceWriter public st ...

  6. canvas设置渐变

    canvas设置渐变 方法 createLinearGradient(x1, y1, x2, y2) 线性渐变 createRadialGradient(x1, y1, r1, x2, y2, r2) ...

  7. canvas给图形添加颜色

    canvas给图形添加颜色 合法属性 ctx.fillStyle = 'orange'; ctx.fillStyle = '#FFA500'; ctx.fillStyle = 'rgb(255, 16 ...

  8. C# 子窗体关闭父窗体的简单方法

    当在一个窗体中调用另一个窗体时,涉及到子窗体关闭的同时,父窗体同时关闭. 例如: 在窗体1中,单击按钮调用窗体2,通过this传递 private void button1_Click(object ...

  9. Centos 7.2基础安装和配置(含分区方案建议)

    景:windows桌面运维为主的我,前几天接到一个去某客户上架安装服务器的工作任务,含糊的说要上架几台服务器顺便安装Centos系统,于是我便下载了一个Centos7.2版本的镜像,顺利的用USBwr ...

  10. leetcode9

    public class Solution { public bool IsPalindrome(int x) { ) { return false; } var str = x.ToString() ...