力扣 - 剑指Offer 35.复杂链表的复制
题目
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
示例 1:

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
示例 2:

输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]
示例 3:

输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]
示例 4:
输入:head = []
输出:[]
解释:给定的链表为空(空指针),因此返回 null。
思路1
我们利用HashMap,key存储旧的链表,value存储新的链表,先将链表复制一份到Map中,然后再同步遍历来设置他的next和random指针。最后返回复制的链表的head即可。
代码实现
class Solution {
public Node copyRandomList(Node head) {
HashMap<Node, Node> map = new HashMap<>();
//由于待会还要用到head,所以创建一个Node用指向head
Node cur = head;
//复制链表到HashMap中
while (cur != null) {
map.put(cur, new Node(cur.val));
cur = cur.next;
}
cur = head;
while (cur != null) {
//设置next指向,将复制的链表连接起来
map.get(cur).next = map.get(cur.next);
//将复制的链表的random指向与原来链表同步
map.get(cur).random = map.get(cur.random);
cur = cur.next;
}
//获取map中head对应的value(即新链表)返回
return map.get(head);
}
}
思路2
分三步来解决:
- 先将每个结点复制,然后跟在原来结点的后面,并且连接起来
- 设置复制的结点的random指向和原来的链表的random指向一样
- 将链表分离即可。
代码实现
class Solution {
public Node copyRandomList(Node head) {
copy(head);
randomDirect(head);
return getResult(head);
}
//第一步:先将每个结点复制,然后跟在原来结点的后面
public void copy(Node head) {
//复制每个结点到当前结点的下一个结点
while (head != null) {
//克隆当前结点
Node cloneNode = new Node(head.val);
//获取下一个要复制的结点
Node nextNode = head.next;
//将复制的结点和原来的链表链接起来
head.next = cloneNode;
cloneNode.next = nextNode;
//将head指向下一个要复制的结点
head = nextNode;
}
}
//第二步:设置复制的结点的random指向和原来的链表的random指向一样
public void randomDirect(Node head) {
while (head != null) {
//获取原链表对应的复制的结点
Node cloneNode = head.next;
//如果是空的会就跳过,否则会触发空指针异常
if (head.random != null) {
Node direct = head.random;
//必须要用next才能指向我们复制的结点,如果没有加next那么就会指向原来的结点,不合题意
cloneNode.random = direct.next;
}
head = cloneNode.next;
}
}
//第三步:将旧链表与新链表分离
public Node getResult(Node head) {
//如果输入的head为空,那么直接返回
if (head == null) {
return null;
}
//获取复制的链表的头结点
Node cloneNode = head.next;
Node cloneHead = head.next;
//将head的下一个结点修改为原来链表的下一个结点,然后再将head指向它
head.next = head.next.next;
head = head.next;
while (head != null) {
cloneNode.next = head.next;
cloneNode = cloneNode.next;
//由于原来的链表顺序也不能修改,所以两个链表必须全部分离,不能有依赖
head.next = head.next.next;
head = head.next;
}
return cloneHead;
}
}
力扣 - 剑指Offer 35.复杂链表的复制的更多相关文章
- 剑指 Offer 35. 复杂链表的复制
剑指 Offer 35. 复杂链表的复制 Offer_35 题目详情 方法一 可以使用一个HashMap来存储旧结点和新结点的映射. 这种方法需要遍历链表两遍,因为需要首先知道映射关系才能求出next ...
- 【Java】 剑指offer(35) 复杂链表的复制
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 请实现函数ComplexListNode* Clone(Compl ...
- 剑指offer——35复杂链表的复制
这题很是巧妙. 突破了常规思维. 竟然可以把传入进来的链表和复制的链表链在一起.然后再算出slibling指针.最后在分离. 直接把空间复杂度变为O(1)了. 很巧妙,很实用. 题目: 请实现函数Co ...
- 每日一题 - 剑指 Offer 35. 复杂链表的复制
题目信息 时间: 2019-06-28 题目链接:Leetcode tag: 链表 难易程度:中等 题目描述: 请实现 copyRandomList 函数,复制一个复杂链表.在复杂链表中,每个节点除了 ...
- 【剑指Offer】复杂链表的复制 解题报告(Python)
[剑指Offer]复杂链表的复制 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews 题 ...
- 《剑指offer》复杂链表的复制
本题来自<剑指offer> 反转链表 题目: 思路: C++ Code: Python Code: 总结:
- 力扣 - 剑指 Offer 06. 从尾到头打印链表.md
题目 剑指 Offer 06. 从尾到头打印链表 思路1(递归) 首先先遍历整个脸表,计算出链表的长度(用于初始化数组).然后进行递归,从链表头部递归到尾部,这期间什么都不做,直到递归到最后一个节点的 ...
- 力扣 - 剑指 Offer 22. 链表中倒数第k个节点
题目 剑指 Offer 22. 链表中倒数第k个节点 思路1(栈) 既然要倒数第k个节点,那我们直接把所有节点放到栈(先进后出)里面,然后pop弹出k个元素就可以了 代码 class Solution ...
- 力扣 - 剑指 Offer 52. 两个链表的第一个公共节点
题目 剑指 Offer 52. 两个链表的第一个公共节点 思路1(栈) 若两个链表相遇,则从它开始相遇的地方到链表末尾应该都是相同的,那么我们可以将两个链表分别放入两个栈中,然后依次循环比较两个栈顶的 ...
随机推荐
- 利用rtklib处理GPS以及北斗数据详解
利用rtklib开源代码处理GPS以及北斗数据详解 在GNSS领域最基础的工作是这些GNSS系统的定位工作,对于绝大多数研究者,自己着手完成这些工作是一个"鸡肋":完全独立设计的话 ...
- 怎么写一个Activity
a.新建一个类继承Actitvity b.重写oncreate方法 setContentView(R.layout.XXX);//设置布局文件 c.注册activity <activity an ...
- ubuntu1804 snort base
1.环境准备 apt安装 sudo apt-get update -y sudo apt-get dist-upgrade -y sudo apt-get install -y zlib1g-dev ...
- CSS的背景
CSS的背景 1. 背景颜色background-color div { background-color: 颜色值; } 一般情况下元素背景颜色默认是transparent(透明). 2. 背景图片 ...
- 多测师讲解pyhon__hashlib_高级讲师肖sir
一.加密,加密成16进制的字符串 # import hashlib # 导入hashlib模块# md = hashlib.md5() # 获取一个md5加密算法对象# md.update('需要加密 ...
- HDU-1051 Wooden Sticks--线性动归(LIS)
题目大意:有n根木棍(n<5000),每根木棍有一个长度l和重量w(l,w<10000),现在要对这些木头进行加工,加工有以下规则: 1.你需要1分钟来准备第一根木头. 2.如果下一根木头 ...
- [leetcode] 周赛 211
比赛题目:https://leetcode-cn.com/circle/discuss/luvHfG/ 两个相同字符之间的最长子字符串 题目:5543. 两个相同字符之间的最长子字符串. 开始理解错题 ...
- 每天一个linux命令:ps命令
Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进 ...
- ps 批量kill进程
Linux下批量kill掉进程 ps -ef|grep java|grep -v grep|cut -c 9-15|xargs kill -9 管道符"|"用来隔开两个命令,管 ...
- 【抽五分钟】使用VuePress创建在线文档中心
内容目录 安装初始化核心配置导航栏配置侧边栏配置静态资源配置nginx部署typora编写 安装初始化 全局安装 npm install -g vuepress 创建目录 mkdir vurepre ...