复杂链表的复制
题目描述:有一个复杂链表,其结点除了有一个Next指针指向下一个结点外,还有一个random指向链表中的任意结点或者NULL。其链表的定义如下:
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
请实现 public RandomListNode Clone(RandomListNode pHead) 函数实现克隆一个链表。
解决思路:
暴力的解法:首先只复制链表,不管random指针。然后再遍历原链表,复制random指针。复制random指针的方法是根据原链表从头开始,而指向复制链表的指针也同时开始,判断random指针是指向哪一个结点,然后根据位置对应,把复制链表的指针的位置赋值给random。好吧,其实画个图很简单。
![]()
import java.util.*;
public class Main {
class RandomListNode{
public int label;
public RandomListNode next = null;
public RandomListNode random = null;
public RandomListNode(int label){
this.label = label;
}
}
public RandomListNode Clone(RandomListNode pHead){
if(pHead == null)
return null;
RandomListNode temp = pHead;
RandomListNode head = new RandomListNode(temp.label);
RandomListNode p = head;
if(temp.next != null)
temp = temp.next;
//首先把只复制基本的链表
while (temp != null){
RandomListNode node = new RandomListNode(temp.label);
p.next = node;
node.next = null;
p = p.next;
temp = temp.next;
}
//然后复制random指针
p = head;
temp = pHead;
while (p != null){
if(temp.random == null){
p.random = null;
p = p.next;
temp = temp.next;
continue;
}
RandomListNode t = pHead;
RandomListNode q = head;
while(t != null){ //t和q只需要判断一个就行
if(temp.random == t)
break;
t = t.next;
q = q.next;
}
p.random = q;
p = p.next;
temp = temp.next;
}
return head;
}
public static void main(String[] args) {
RandomListNode node1 = new Main().new RandomListNode(1);
RandomListNode node2 = new Main().new RandomListNode(2);
RandomListNode node3 = new Main().new RandomListNode(3);
RandomListNode node4 = new Main().new RandomListNode(4);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = null;
node1.random = null;
node3.random = node1;
RandomListNode head = new Main().Clone(node1);
System.out.println(head);
System.out.println(head.random);
head = head.next;
System.out.println(head.random);
head = head.next;
System.out.println(head.random);
}
}
- 本题一种巧妙的解法是,将每个复制后的结点都跟在原结点后面,步骤如下:
1.复制每个结点,如复制结点A得到A1,并将A1插到结点A后面。
2.重新遍历链表,复制老结点的随机指针给新结点,如A1.random = A.random.next
3.拆分链表,将原链表拆分成原链表和复制后的链表
import java.util.*;
public class Main {
class RandomListNode{
public int label;
public RandomListNode next = null;
public RandomListNode random = null;
public RandomListNode(int label){
this.label = label;
}
}
public RandomListNode Clone(RandomListNode pHead){
if(pHead == null)
return null;
RandomListNode currentNode = pHead;
//1.复制每个结点,如复制结点A得到A1,将A1插到A后面
while (currentNode != null){
RandomListNode copyNode = new RandomListNode(currentNode.label);
RandomListNode p = currentNode.next;
copyNode.next = p;
currentNode.next = copyNode;
currentNode = p;
}
//2.重新遍历链表,复制老结点的随机指针给新结点,如A1.random = A.random.next
currentNode = pHead;
while (currentNode != null){
currentNode.next.random = (currentNode.random == null) ? null : currentNode.random.next;
currentNode = currentNode.next.next;
}
//3.拆分链表,将原链表拆分成原链表和复制后的链表
currentNode = pHead;
RandomListNode copyHead = currentNode.next;
while (currentNode != null){
RandomListNode p = currentNode.next;
currentNode.next = p.next;
if(p.next != null)
p.next = p.next.next;
currentNode = currentNode.next;
}
return copyHead;
}
public static void main(String[] args) {
RandomListNode node1 = new Main().new RandomListNode(1);
RandomListNode node2 = new Main().new RandomListNode(2);
RandomListNode node3 = new Main().new RandomListNode(3);
RandomListNode node4 = new Main().new RandomListNode(4);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = null;
node1.random = null;
node3.random = node1;
RandomListNode head = new Main().Clone(node1);
System.out.println(head);
System.out.println(head.random);
head = head.next;
System.out.println(head.random);
head = head.next;
System.out.println(head.random);
}
}

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
用python(pyvmomi)管理vmware ESXi/vCenter
环境 开发环境:Ubuntu 18.04 + python3.7以下环境经过测试都可以使用:centos 6/7 + python3.4/3.6/3.7 和windows 7/2016 +python3.4/3.6/3.7 安装必要模块pyvmomi pip install pyvmomi 如果是linux系统有pip2和pip3 两个版本,需要使用 pip3 install pyvmomi 代码 host='ESXi 机器ip' user='root' password='密码' port=443#端口 context = None if hasattr(ssl, '_create_unverified_context'): context = ssl._create_unverified_context() si = SmartConnect(host=host,user=user,pwd=password,port=port,sslContext=context) if not si: print("帐号密码有问题") atexit.register(Disconnect, si...
-
下一篇
有人说学了C语言,两天就能把Java学会,再过两个星期就可以找工作了,是真的吗?
作为一个做过十几年代码的老司机,学习编程如果真的这么简单就不会导致现在各大公司还在喊着招不到人的情况了,虽然编程领域里面有触类旁通的说法,但这个说法只是针对于对于一种编程已经掌握到一定程度了,不是简单的学过或者做过就可以轻松的转向别的编程语言了,换句话来讲如果一种编程语言学的马马虎虎,也不要指望第二种编程语言能好到什么程度,编程语言不在于多,而在于精,只要在一个方向做到极致,找到编程的感觉,再切入新的编程语言的确会快很多。 正常来讲如果已经掌握一种或者多种编程语言再去学习新的编程语言,就那笔者的经验来讲差不多十天左右就能开始跟着做项目,为什么会有这种判断不在于编程语言本身有多简单,主要来讲编程语言只是一种工具而已,真正关切到编程核心的东西是编程思想,不同的编程语言编程思想是想通的,所以切换到新的编程语言只是切换的编程语言的语法,编程思想还是哪些,所以从心理上就存在优越感,有了底气学习起来自然就快了许多,其实很多编程语言虽然具体不完全的一致,但指导思想基本上一致,所以学习了基本的语法之后直接开始上手做东西就可以了,当然在做的过程中如果遇到不懂的直接查资料,邮局不太好听话,叫现编现买,其实...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8编译安装MySQL8.0.19
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL数据库在高并发下的优化方案
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Red5直播服务器,属于Java语言的直播服务器
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题