力扣 - 剑指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(栈) 若两个链表相遇,则从它开始相遇的地方到链表末尾应该都是相同的,那么我们可以将两个链表分别放入两个栈中,然后依次循环比较两个栈顶的 ...
随机推荐
- jquery购物车全选,取消全选,计算总金额
这是html代码 <div class="gwcxqbj"> <div class="gwcxd center"> <div cl ...
- 多测师讲解selenium_alert弹框定位_高级讲师肖sir
from selenium import webdriverfrom time import sleepdrvier=webdriver.Chrome()url=r'F:\dcs\DCS课程安排\se ...
- 福州11911.562(薇)xiaojie:福州哪里有xiaomei
福州哪里有小姐服务大保健[微信:11911.562倩儿小妹[福州叫小姐服务√o服务微信:11911.562倩儿小妹[福州叫小姐服务][十微信:11911.562倩儿小妹][福州叫小姐包夜服务][十微信 ...
- xuexi
1.内存的编址方法就是内存地址与内存单元格一一对应且永久绑定.计算机的cpu只认识内存地址,不关心内存单元格的位置和内容.通过硬件的设计来达到通过内存地址找到内存单元格. 2.内存的编址是以字节为单位 ...
- linux学习(一)--启动文件bootsect.s
这是linux由BIOS加载后执行的第一段的启动程序代码,即文件 boot/bootsect.s 首先附图,简单介绍一下从开机加电到第一段linux代码执行的简要过程 1 .globl begte ...
- php-fpm 高并发 参数调整 转
工作中经常会遇到会给客户配置服务器,其中有的客户还会有并发量要求,其中也会必须要用负载均衡承载压力的.增加服务器数量肯定能有效的提升服务器承载能力,但只有根据目前已有配置设置好单台服务器才能更好的发挥 ...
- Vue slot插槽通俗解释
slot内容分发是Vue的Api来源 <div id="app"> <my-list> {{msg}} </my-list> </div& ...
- Linux命令的执行
为什么在提示符下命令可以被执行呢? 执行命令过程 输入命令后回车,提请shell程序找到键入命令所对应的可执行程序或代码,并由其分析后提交给内核分配资源将其运行起来 shell本身也是一个程序,只不过 ...
- HTML编辑器(1)
前言 现在网上有很多这样的HTML编辑器,这种编辑器无疑给人带来了很多方便,所以自己也想尝试制作一款这样的HTML编辑器,既然要制作,那就肯定是先把UI搭起来,再慢慢完善功能 设计思路 我的思路就是将 ...
- Linux入门到放弃之八《任务计划管理》
任务计划管理 1.每周一下午5:50将/data目录下的所有目录和文件归档并压缩为:backup.tar.gz 放在/home/backup目录下. 先新建/data目录,并在目录中随意生成几个文件 ...