Problem:
  复制含有随机指针节点的链表
  【题目】 一种特殊的链表节点类描述如下:
  public class Node {
  public int value; public Node next; public
  Node rand;
  public Node(int data) { this.value = data; }
  }
  Node类中的value是节点值,next指针和正常单链表中next指针的意义
  一 样,都指向下一个节点,rand指针是Node类中新增的指针,这个指
  针可 能指向链表中的任意一个节点,也可能指向null。 给定一个由
  Node节点类型组成的无环单链表的头节点head,请实现一个 函数完成
  这个链表中所有结构的复制,并返回复制的新链表的头节点。 进阶:
  不使用额外的数据结构,只用有限几个变量,且在时间复杂度为 O(N)
  内完成原问题要实现的函数。

Solution :
  一:
    使用hash_map来进行存放原链表
    key=原链表, value=新建链表的节点
    然后根据原链表的结构将新链表进行结构构造
二:
    将原链表数组原地复制两份:
    head 1 2 3 4 5 6 NULL
    复制成: head head' 1 1' 2 2' 3 3' 4 4' 5 5' 6' 6' NULL
    然后Copy则取带'的节点就行

  1 #pragma once
  2 #include <iostream>
  3 #include <hash_map>
  4
  5 using namespace std;
  6
  7 struct Node
  8 {
  9     int val;
 10     Node *rand;
 11     Node *next;
 12     Node(int a = -1) :val(a), rand(NULL), next(NULL) {}
 13 };
 14
 15
 16 Node* CopeListDeep(Node* head)
 17 {
 18     hash_map<Node*, Node*>map;
 19     Node* p = head;
 20     while (p)//新建链表的结构
 21     {
 22         map[p] = new Node(-1);
 23         p = p->next;
 24     }
 25
 26     p = head;
 27     while (p)//重构新链表的结构
 28     {
 29         map[p]->val = p->val;
 30         map[p]->next = map[p->next];
 31         map[p]->rand = map[p->rand];
 32         p = p->next;
 33     }
 34     return map[head];
 35 }
 36
 37 Node* CopeListDeep2(Node* head)
 38 {
 39     Node* cur = head;
 40     Node* next = NULL;
 41     while (cur)//将原链表复制两份
 42     {
 43         next = cur->next;
 44         cur->next = new Node(cur->val);
 45         cur->next->next = next;//此处为复制两份的代码
 46         cur = next;
 47     }
 48
 49     cur = head;
 50     Node* copyHead = NULL;//为了区分原链
 51     //先复制rand节点
 52     while (cur)//将新建的节点的结构进行重构
 53     {
 54         next = cur->next->next;//原链表的遍历
 55         copyHead = cur->next;
 56         copyHead->rand = ((cur->rand) == NULL ? NULL : (cur->rand)->next);
 57         cur = next;
 58     }
 59     //copyHead已经是链表的末尾NULL
 60     cur = head;
 61     Node* res = head->next;
 62     while (cur)
 63     {
 64         next = cur->next->next;
 65         copyHead = cur->next;
 66         cur->next = next;
 67         copyHead->next = (next == NULL) ? NULL : next->next;
 68         cur = next;
 69     }
 70
 71     //为什么不一次性将原链表进行还原和复制链表进行重构?
 72     //因为一旦原链表前半部分还原,而后半部分一旦有rand指向前半部分,原链表是能找到所指向
 73     //的节点,但由于前半部分原链表已经还原了,所以复制链表的rand无法依据原链表的位置找到自己rand所指向的节点,
 74     //故得先将rand  copy出来。
 75     return res;
 76
 77 }
 78
 79
 80 void Test()
 81 {
 82     Node *head = new Node(-1);
 83     head->next = new Node(1);
 84     head->next->next = new Node(2);
 85     head->next->next->next = new Node(3);
 86     head->next->next->next->next = new Node(4);
 87     head->next->next->next->next->next = new Node(5);
 88     head->next->next->next->next->next->next = new Node(6);
 89     head->next->next->next->next->next->next->next = NULL;
 90
 91
 92     head->rand = NULL;
 93     head->next->rand = head->next->next->next->next->next->next;
 94     head->next->next->rand = head->next->next->next->next->next->next;
 95     head->next->next->next->rand = head->next->next->next->next->next;
 96     head->next->next->next->next->rand = head->next->next->next;
 97     head->next->next->next->next->next->rand = NULL;
 98     head->next->next->next->next->next->next->rand = head->next->next->next->next;
 99
100
101     cout << "打印原链表:" << endl;
102     Node*p = head->next;
103     while (p)
104     {
105         cout << "next: " << p->val << "   rand: " << ((p->rand) ? p->rand->val : -1) << endl;
106         p = p->next;
107     }
108
109     cout << endl << "打印新链表:" << endl;
110     p = CopeListDeep2(head)->next;
111     while (p)
112     {
113         cout << "next: " << p->val << "   rand: " << ((p->rand) ? p->rand->val : -1) << endl;
114         p = p->next;
115     }
116
117
118 }

转载于:https://www.cnblogs.com/zzw1024/p/10993026.html

左神算法基础班3_13深度拷贝含有随机指针的链表相关推荐

  1. 左神算法基础班4_4_3在二叉树中找到一个节点的后继节点

    Problem: 在二叉树中找到一个节点的后继节点 [题目] 现在有一种新的二叉树节点类型如下: public class Node { public int value; public Node l ...

  2. 0206.BFPRT在一大堆数中求其前k大或前k小的问题,简称TOP-K问题(左神算法基础班源码)

    package basic_class_02;/*** * 在一大堆数中求其前k大或前k小的问题,简称TOP-K问题.* 而目前解决TOP-K问题最有效的算法即是BFPRT算法**/ public c ...

  3. 13.在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组的小和。(左神算法基础班源码)

    package basic_class_01; /*** *小和问题在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和.求一个数组的小和.例子:[1,3,4,2,5]1左边比1小的数 ...

  4. 左神算法中级班第三课[C++代码]

    左神算法中级班第三课[C++代码] 第一题:流水线打包问题[阿里原题] 代码 第二题 代码 第三题:打印螺旋矩阵 代码 第四题 代码 第五题:判读aim是否在矩阵中 代码 第七题:topK问题 代码 ...

  5. java取余数的函数_左神算法基础:哈希函数和哈希表

    笔者在读研刚开始的时候,偶尔看面经,有这样一个问题:只用2GB内存在20亿个整数中找到出现次数最多的数,当时的我一脸懵逼,怎么去思考,20亿个数?What The Fuck! 但是,看完今天的文章,你 ...

  6. igs无法分配驱动器映射表_左神算法基础:哈希函数和哈希表

    笔者在读研刚开始的时候,偶尔看面经,有这样一个问题:只用2GB内存在20亿个整数中找到出现次数最多的数,当时的我一脸懵逼,怎么去思考,20亿个数?What The Fuck! 但是,看完今天的文章,你 ...

  7. 《左神算法初级班》第四节课:二叉树结构

    目录: 1)二叉树结构 2)二叉树的递归与非递归遍历 3)打印二叉树 4)判断搜索二叉树 5)判断完全二叉树 6)判断平衡二叉树 7)折纸问题 8)二叉树节点的前驱节点与后继节点 9)二叉树的序列化和 ...

  8. 【搞定左神算法初级班】第4节:二叉树及相关常见面试题

    目 录: 题目1:实现二叉树的先序.中序.后序遍历[递归方式和非递归方式] 题目2:在二叉树中找到一个节点的后继节点 题目3:介绍二叉树的序列化和反序列化 题目4:折纸问题 题目5:判断一棵二叉树是否 ...

  9. 左神算法初级班笔记4:二叉树

    文章目录 01 | 实现二叉树的先序.中序.后序遍历,包括递归方式和非递归 方式 1.递归版本: 2. 非递归版本: 02 | 在二叉树中找到一个节点的后继节点 03 | 介绍二叉树的序列化和反序列化 ...

最新文章

  1. 优达学城python项目P1:搜索和探索近地天体(NEOs)
  2. PHP Memcached应用实现代码
  3. python3 正则表达式 匹配多个 单词 字符串
  4. 查拉斯图拉的“没落”
  5. linux文本编辑利器-vim
  6. 网页设计中的默认字体样式详解
  7. ComponentBase.createMetaData and manifest.json oRoute
  8. 【linux】linux命令如何查看文件、文件夹的属性,包括大小、修改时间、谁修改的...
  9. 网站制作---eWebeditor不兼容IE8问题的解决方法
  10. 目标检测(十一)--ConvNets目标检测概述
  11. 【转】谈一谈PHP字串清除空格函数不安全
  12. 小松鼠短视频完开源源码
  13. 微信群解答_各月各旬降水量均值_巧用groupby
  14. android自带浏览器调试,Android 手机浏览器调试使用Chrome进行调试实例详解
  15. FDTD Solutions自学整理笔记入门教程(2):PML
  16. linux 内核 mtd读取,linux内核 mtd分区
  17. 解决虚拟机下光标闪烁问题
  18. 为了中国---我国民用客机深度报道(第三部分下)
  19. Ubuntu20.04安装Nvidia驱动——4060显卡(黑屏解决方法)
  20. python 一张图画多条线_Python画多条线在一个图里

热门文章

  1. Android打Path的方法
  2. ZooKeeper客户端ZKClient使用
  3. 今天看了一下攒机配置 5000元以下 参考以下
  4. 给初恋女孩的信....
  5. Firefox beta 开始原生支持 Windows 10 ARM64
  6. win7下显示linux文本文件不换行
  7. 服务部署如何做到高可用?这份“三级跳”秘籍送给你\n
  8. 关于mac的一些常用操作记录
  9. Neural Representation Learning in NLP | 实录·PhD Talk #07
  10. mysql 快速生成百万条测试数据