题目

请实现 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

分三步来解决:

  1. 先将每个结点复制,然后跟在原来结点的后面,并且连接起来
  2. 设置复制的结点的random指向和原来的链表的random指向一样
  3. 将链表分离即可。

代码实现

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.复杂链表的复制的更多相关文章

  1. 剑指 Offer 35. 复杂链表的复制

    剑指 Offer 35. 复杂链表的复制 Offer_35 题目详情 方法一 可以使用一个HashMap来存储旧结点和新结点的映射. 这种方法需要遍历链表两遍,因为需要首先知道映射关系才能求出next ...

  2. 【Java】 剑指offer(35) 复杂链表的复制

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 请实现函数ComplexListNode* Clone(Compl ...

  3. 剑指offer——35复杂链表的复制

    这题很是巧妙. 突破了常规思维. 竟然可以把传入进来的链表和复制的链表链在一起.然后再算出slibling指针.最后在分离. 直接把空间复杂度变为O(1)了. 很巧妙,很实用. 题目: 请实现函数Co ...

  4. 每日一题 - 剑指 Offer 35. 复杂链表的复制

    题目信息 时间: 2019-06-28 题目链接:Leetcode tag: 链表 难易程度:中等 题目描述: 请实现 copyRandomList 函数,复制一个复杂链表.在复杂链表中,每个节点除了 ...

  5. 【剑指Offer】复杂链表的复制 解题报告(Python)

    [剑指Offer]复杂链表的复制 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews 题 ...

  6. 《剑指offer》复杂链表的复制

    本题来自<剑指offer> 反转链表 题目: 思路: C++ Code: Python Code: 总结:

  7. 力扣 - 剑指 Offer 06. 从尾到头打印链表.md

    题目 剑指 Offer 06. 从尾到头打印链表 思路1(递归) 首先先遍历整个脸表,计算出链表的长度(用于初始化数组).然后进行递归,从链表头部递归到尾部,这期间什么都不做,直到递归到最后一个节点的 ...

  8. 力扣 - 剑指 Offer 22. 链表中倒数第k个节点

    题目 剑指 Offer 22. 链表中倒数第k个节点 思路1(栈) 既然要倒数第k个节点,那我们直接把所有节点放到栈(先进后出)里面,然后pop弹出k个元素就可以了 代码 class Solution ...

  9. 力扣 - 剑指 Offer 52. 两个链表的第一个公共节点

    题目 剑指 Offer 52. 两个链表的第一个公共节点 思路1(栈) 若两个链表相遇,则从它开始相遇的地方到链表末尾应该都是相同的,那么我们可以将两个链表分别放入两个栈中,然后依次循环比较两个栈顶的 ...

随机推荐

  1. SpringCloud Alibaba系列(三) Sentinel热点参数限流

    愿你生命中有够多的云翳,造就一个美好的黄昏 欢迎关注公众号[渣男小四],一个喜欢技术更喜欢艺术的青年 一.介绍 热点即经常访问的数据.很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据 ...

  2. 如何用5000行JS撸一个关系型数据库

    首先声明,我不是标题党,我真的是用5000行左右的JS实现了一个轻量级的关系型数据库JSDB,核心是一个SQL编译器,支持增删改查. 源代码放到github上了:https://github.com/ ...

  3. C# 中的延时的方法。

    转载:https://blog.csdn.net/caixiexin/article/details/5769121 System.Threading.Thread.Sleep(2000); 其中20 ...

  4. Jenkins从节点上构建自动化测试项目时报错:java.io.IOException: Unexpected termination of the channel

    在mac电脑上配置了Jenkins从节点,在该从节点上构建app UI 自动化测试项目,运行一些用例后报如下错误: java.io.EOFException at java.io.ObjectInpu ...

  5. linux块设备驱动---程序设计(转)

    块设备驱动注册与注销 块设备驱动中的第1个工作通常是注册它们自己到内核,完成这个任务的函数是 register_blkdev(),其原型为:int register_blkdev(unsigned i ...

  6. 多测师讲解_肖sir _rf报错归纳(1):

    错误一: 报错原因:文件格式 解决方案: 修改文件格式,将txt改成robot格式   错误二: rf 运行以后出现乱码现象 解决方案: 打开python的安装路径下:C:\python37\Lib\ ...

  7. Java代码实现计算器加减乘除简易功能

    package test; import javax.swing.; import java.awt.; import java.awt.event.KeyAdapter; import java.a ...

  8. 搭建分布式 Redis Cluster 集群与 Redis 入门

    目录 Redis 集群搭建 Redis 是啥 集群(Cluster) Redis Cluster 说明 Redis Cluster 节点 Redis Cluster 集群模式 不能保证一致性 创建和使 ...

  9. es7.8启动报错 说是主节点没找到

    p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 0, 0, 1); background-color: rgba(255, 255, 255, 1 ...

  10. centos8平台:用fontconfig安装及管理字体(fc-list/fc-match/fc-cache)

    一,fc-list所属的rpm包 [root@blog ~]$ whereis fc-list fc-list: /usr/bin/fc-list /usr/share/man/man1/fc-lis ...