热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java详解剑指offer面试题35复杂链表的复制

Java详解剑指offer面试题35–复杂链表的复制输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,
Java详解剑指offer面试题35–复杂链表的复制

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

复杂链表的定义如下

private class RandomListNode {int label;RandomListNode next = null;RandomListNode random = null;RandomListNode(int label) {this.label = label;}
}

**注意不可将链表头结点引用返回,所以需要自己new一个结点出来。**要完成复杂链表的复制,第一步要完成普通链表的复制,普通链表的复制可以用一个栈复制每一个结点,之后逐个弹出并连接起来。对于本题有两种策略:

第一种是,在复制普通链表时,将原链表结点和复制链表的结点成对存入HashMap中,建立一对一的映射。当进行随机结点复制时,遍历原链表,如果某结点的随机结点不为空,那么根据HashMap能以O(1)的时间找到对应的复制链表结点中,若原始链表的结点M指向随机结点S,那么复制链表的M’也要指向结点S’,这种方法时间复杂度为O(N),但空间复杂度为O(N)。

更好的方法是,插入、连接、拆分三步法。

  • 插入:在原始链表的每个结点后插入一个值和它一样的新结点;则有oriNode.next == cloneNode这样的关系;
  • 连接随机结点:遍历插入新结点后的链表,在访问原始链表中的那些结点时,判断其是否有随机结点,有的话cloneNode.random = oriNode.random.next这里oriNode.random.next表示原始链表随机结点的下一个结点,其实就是复制链表的随机结点。
  • 拆分原始链表和复制链表:将奇数结点相连就是原始链表,将偶数结点相连就是我们想要的复制链表。返回复制链表的头结点即可。

package Chap4;/*** 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head* (注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)*/
public class CloneLinkedList {private class RandomListNode {int label;RandomListNode next = null;RandomListNode random = null;RandomListNode(int label) {this.label = label;}}/*** 1、为每个结点的next插入一个和该结点的值一样的结点* 2、设置每个复制结点的random结点* 3、将链表拆分,返回复制链表的头结点** @param pHead 原链表头结点* @return 复制链表的头结点,不可直接返回原链接结点的引用,必须使用new出来的RandomListNode*/public RandomListNode Clone(RandomListNode pHead) {if (pHead == null) return null;copyNode(pHead);setCloneRandomNode(pHead);return splitList(pHead);}// 1. 为每个结点的next插入一个和该结点的值一样的结点private void copyNode(RandomListNode head) {RandomListNode cur = head;while (cur != null) {RandomListNode cloneNode = new RandomListNode(cur.label);cloneNode.next = cur.next;cur.next = cloneNode;cur = cloneNode.next;}}// 2. 设置每个复制结点的randomprivate void setCloneRandomNode(RandomListNode head) {RandomListNode cur = head;while (cur != null) {RandomListNode cloneNode = cur.next;if (cur.random != null) {cloneNode.random = cur.random.next;}cur = cloneNode.next;}}// 3. 拆分链表private RandomListNode splitList(RandomListNode head) {RandomListNode cur = head;RandomListNode cloneHead = cur.next;while (cur != null) {RandomListNode cloneNode = cur.next;cur.next = cur.next.next;if (cloneNode.next != null) {cloneNode.next = cloneNode.next.next;}cur = cur.next;}return cloneHead;}
}

该方法没有用到额外的空间,仅仅是对每个结点进行插入、删除操作等。时间复杂度为O(N).


本文参考文献:
[1]github.com/haiyusun/data-structures


推荐阅读
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 标题: ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Java程序设计第4周学习总结及注释应用的开发笔记
    本文由编程笔记#小编为大家整理,主要介绍了201521123087《Java程序设计》第4周学习总结相关的知识,包括注释的应用和使用类的注释与方法的注释进行注释的方法,并在Eclipse中查看。摘要内容大约为150字,提供了一定的参考价值。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • CentOS7.8下编译muduo库找不到Boost库报错的解决方法
    本文介绍了在CentOS7.8下编译muduo库时出现找不到Boost库报错的问题,并提供了解决方法。文章详细介绍了从Github上下载muduo和muduo-tutorial源代码的步骤,并指导如何编译muduo库。最后,作者提供了陈硕老师的Github链接和muduo库的简介。 ... [详细]
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
  • #define_CRT_SECURE_NO_WARNINGS#includelist.h#includevoidSListInit(PNode*pHead ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
author-avatar
功民昌
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有