题目

请实现 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. centos7修改ssh端口及添加ssh监听端口

    ssh 修改默认端口 [root@node-1 ~]# vi /etc/ssh/sshd_config 修改port 为 5522 重启[root@node-1 ~]# systemctl resta ...

  2. uBuntu安装其他版本Python

    问题描述:阿里云服务器uBuntu版本为16.04,默认Python版本为2.7.12和3.5.2,但是FastAPI,仅支持3.6+版本,因此需要更高版本的Python. 注意:系统自带的Pytho ...

  3. Arduino 模拟引脚

    Arduino的模拟引脚的引用,网上不错的一篇文章 参考:http://blog.sina.com.cn/s/blog_156e62ef90102xjio.html 模拟引脚 本文是对于Arduino ...

  4. P2832 行路难

    题面 Link 题目背景 小X来到了山区,领略山林之乐.在他乐以忘忧之时,他突然发现,开学迫在眉睫 题目描述 山区有 \(n\) 座山.山之间有 \(m\) 条羊肠小道,每条连接两座山,只能单向通过, ...

  5. .NET 云原生架构师训练营(模块一 架构师与云原生)--学习笔记

    目录 什么是软件架构 软件架构的基本思路 单体向分布式演进.云原生.技术中台 1.1 什么是软件架构 1.1.1 什么是架构? Software architecture = {Elements, F ...

  6. iptables 和firewalld 区别

    在RHEL7里有几种防火墙共存:firewalld.iptables.ebtables,默认是使用firewalld来管理netfilter子系统,不过底层调用的命令仍然是iptables等. fir ...

  7. mac电脑上安装appium报错:Failed at the appium-chromedriver@4.25.1 postinstall script.

    mac电脑安装appium,装好node.js后,使用命令:npm install appium@1.18.0,安装appium,报如下错误 ``` ERR! errno1 ERR! appium-c ...

  8. 机器学习 KNN算法原理

    K近邻(K-nearst neighbors,KNN)是一种基本的机器学习算法,所谓k近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表.比如:判断一个人的人品,只需要观察 ...

  9. BUUCTF-数据包中的线索 1

    打开题目里面一个pcapng的文件,于是我们拖进wireshark流量分析一波 发现有http的流量,于是我们过滤http 让后追踪http,然后发现base64的编码, 于是我们看到了base64编 ...

  10. RESP协议

    RESP 是 Redis 序列化协议的简写.它是⼀种直观的⽂本协议,优势在于实现异常简单,解析性能极好. Redis 协议将传输的结构数据分为 5 种最⼩单元类型,单元结束时统⼀加上回⻋换⾏符号\r\ ...