题目意思就是说给你给head 的Node节点(这是一个比较特殊的链表),来拷贝出它地结构出来。

方法一:借助HashMap的特性,定义一个HashMap<Node,Node> map对象,key和value都是value类型 ,key来存旧的链表,value来存新的链表。最后利用老节点和新节点的对应关系来实现一个拷贝新的链表。

对于理解哈希表的同学来说,应该不难理解,code也比较容易:

/* 方法一:借助HashMap,定义一个HashMap<Node,Node> map对象,key和value都是value类型 */
public static Node copyListWithRandom1(Node head) {
HashMap<Node, Node> map = new HashMap<Node, Node>();
Node cur = head;
/* 将单链表的所有节点和value对应放进去map对象中 */
while (cur != null) {
map.put(cur, new Node(cur.value));// 这里新建一个节点,这个节点放head的value
cur = cur.next;
}
/* 重新构建链表的结构,注意,此时map对象为map<cur,cur'>,cur'为新建立的节点 */
cur = head;
/*
* 为了让大家更好的理解,我们假设旧节点和旧节点的next还有旧节点rand分别为cur,curJiu,curRand
* (不懂的同学可以先去了解一下hashMap特点)所以有:cur.next= curJiu,cur.rand= curRand
* 因此,为了保持这种结构,就有了(map.get(cur)).next = map.get(cur.next),rand同理。
*/
while (cur != null) {
map.get(cur).next = map.get(cur.next);
map.get(cur).rand = map.get(cur.rand);
cur = cur.next;
}
return map.get(head);

}

方法2:空间复杂度为O(1),只需要几个变量就可以实现,(不过个人觉得还是方法1更方便)不多说了,直接附上图:

编程如下:

/*这个方法空间复杂度为O(1),并且不用用到哈希表,相对来说容易了许多,不过思路比较巧妙,主要就是三步走*/
public static Node copyListWithRandom2(Node head) {
if (head == null) {
return null;
}
/* copy node and link to every node*/
/*从之前的1 2 3 4 5 6
*     6 6 5 3 - 4
* 变为现在的1 1 2 2 3 3 4 4 5 5 6 6 
*  6 - 6 - 5 - 3 - - - 4 -
* 说到底就是添加了next指针,而rand指针不变*/
Node next = null;
Node cur = head; //每个新的操作之前都要对cur赋值
while (cur != null) {
next = cur.next; //先保存这个节点,同时也为了下面的移动方便
cur.next = new Node(cur.value);
cur.next.next = next;
cur = next;//这里千万要注意,它要往前移动
}

/*set copy node rand
* 也就是根据rand来设置新的链表的rand指针
* 从之前的1 2 3 4 5 6
*       6 6 5 3 - 4
* 变为现在的1 1 2 2 3 3 4 4 5 5 6 6 
*  6 6 6 6 5 5 3 3 - - 4 4
* 说到底就是添加了rand指针*/
cur = head; //每个新的操作之前都要对cur赋值
Node curcopy = null;
while (cur != null) {
curcopy = cur.next;
/*这里要先判断cur.rand存不存在*/
if (cur.rand != null) {
curcopy.rand = cur.rand.next;
}
next = cur.next.next;
cur = next; //这里千万要注意,它要往前移动
}

/*split,将新建的链表和旧链表分离
* 断开新链表和旧链表的连接*/
cur = head; //每个新的操作之前都要对cur赋值
Node res = head.next;  //定义这个节点是为了方便返回
while (cur != null) {
next = cur.next.next;  
curcopy = cur.next;
cur.next = next;
/*这里要先判断curcopy.next存不存在*/
if (next != null) {
curcopy.next = next.next;
} else {
curcopy.next = null;
}
cur = next;//这里千万要注意,它要往前移动
}
return res;
}

复制含有随机指针节点的链表~哈希表的使用~(⌒▽⌒)相关推荐

  1. 数据结构与算法之复制含有随机指针节点的链表和两个链表相交的一系列问题

    数据结构与算法复制含有随机指针节点的链表和两个链表相交的一系列问题 目录 复制含有随机指针节点的链表 两个链表相交的一系列问题 1. 复制含有随机指针节点的链表 题目概述 思路:创建一个HashMap ...

  2. 左神算法:复制含有随机指针节点的链表 / 复杂链表的复制(Java版本)

    本题来自左神<程序员代码面试指南>"复制含有随机指针节点的链表"题目. 题目 一种特殊的链表节点类描述如下: public static class Node {pub ...

  3. 链表问题9——复制含有随机指针节点的链表(进阶)

    题目 具体题目信息可以参考上一篇文章. 进阶:不使用额外的数据结构,只用有限几个变量,且在时间复杂度为O(N)内完成原问题要实现的函数. 思路 进阶解法不使用哈希表来保存对应关系,而只采用有限的几个变 ...

  4. 链表问题9——复制含有随机指针节点的链表(初阶)

    题目 public class Node{public int value;public Node next;public Node rand;public Node(int data){this.v ...

  5. 如何复制一个含有随机指针节点的链表

    复制含有随机指针节点的链表 一种特殊的链表节点类描述如下: public class Node {public int value;public Node next;public Node rand; ...

  6. 算法练习day10——190328(根据指定值划分单链表、复制含有rand指针节点的链表、两个单链表相交)

    1.将单向链表按某值划分成左边小. 中间相等. 右边大的形式 [题目] 给定一个单向链表的头节点head, 节点的值类型是整型, 再给定一个整数pivot. 实现一个调整链表的函数, 将链表调整为左部 ...

  7. 左神算法基础班3_13深度拷贝含有随机指针的链表

    Problem: 复制含有随机指针节点的链表 [题目] 一种特殊的链表节点类描述如下: public class Node { public int value; public Node next; ...

  8. 复制带有random指针的单链表

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

  9. LeetCode 1484. 克隆含随机指针的二叉树(哈希/递归)

    文章目录 1. 题目 2. 解题 2.1 原地算法 2.2 哈希表 1. 题目 给你一个二叉树,树中每个节点都含有一个附加的随机指针,该指针可以指向树中的任何节点或者指向空(null). 请返回该树的 ...

最新文章

  1. Api 函数: GetCursorPos 与转换
  2. 连夜撸了一个简易聊天室
  3. Android开发--初识多线程/线程的创建,开启,休眠,中断
  4. highcharts一天时间 与一周时间_如何规划自己一天的时间
  5. TOPAS 命令详解
  6. 软件获取手机的ime权限_【手机谷歌软件下载】【安卓+iOS】老湿机最爱~免翻,获取各种“特殊”资源!...
  7. How to check bad fix
  8. Moving Average
  9. 央视曝光紫砂锅名单_大家看今天中午《每周质量报告》没,美的牌 紫砂锅含有剧毒。家里有这牌子...
  10. python 日志不会按照日期分割_django实现日志按日期分割
  11. sperling指标 matlab,sperling指标计算实验报告
  12. C++ 偏微分数值计算库_一文带你了解计算流体力学CFD及其应用领域
  13. Bellman-Ford 算法及其优化
  14. 2021 年 Web 开发的 7 大趋势,我只能说牛逼!
  15. Android NFC 标签 读写
  16. c语言大学生信息管理系统实验报告,c语言学生信息管理系统实训报告
  17. 微信小程序云开发简单介绍
  18. OpenWrt设置路由器联网(无线)
  19. python start方法_进程方法 run和start的区别
  20. 你真的了解宏吗:浅谈宏定义(#define语句)

热门文章

  1. String.IsNullOrEmpty()方法以及C#中的示例
  2. MyBatis Plus 批量数据插入功能,yyds!
  3. 那些牛逼的数据分析师,SQL用的到底有多溜
  4. 第 1-4 课:Java 中的运算符和流程控制 + 面试题
  5. 生命游戏(game of life)
  6. 安装codeblocks和wxwidgets及opencv
  7. MFC设置对话框背景色及控件颜色
  8. Xshell连接远程Linux服务器失败Could not connect to ‘192.xxx.xx.xxx‘ (port 22): Connection failed.
  9. 计算机程序的构造和解释 python_SICP Python 描述 第三章 计算机程序的构造和解释 3.1 引言...
  10. macos下使用aria2_macOS下 ansible简单安装及基础使用