Java面试题-实现复杂链表的复制代码分享

我们来详细讲解一下“Java面试题-实现复杂链表的复制代码分享”的完整攻略。

确定复制思路

在复制带有随机指针的链表时,我们需要对每个节点都进行深拷贝,并且需要关联原链表中同样的随机指针,因此需要考虑以下几个步骤:

  1. 添加新的节点
  2. 复制原链表中的节点
  3. 连接新旧链表
  4. 复制随机指针

添加新的节点

首先,我们需要对原始链表中的每个节点进行拷贝,并且将拷贝后的节点插入在原始节点的后面。这里我们可以使用链表的插入方法,将新的节点插入到原始节点的后面,具体实现如下:

public static void cloneNodes(ComplexListNode head) {
    ComplexListNode node = head;
    while (node != null) {
        ComplexListNode cloned = new ComplexListNode(node.val);
        cloned.next = node.next;
        cloned.random = null;
        node.next = cloned;
        node = cloned.next;
    }
}

这里我们新创建了一个cloned节点,并且将其插入在node.next的位置上,之后我们更新node节点的指向,指向cloned节点的下一个节点,这样子便完成了新的节点的插入。

复制原链表中的节点

在第一步完成后,我们已经实现了对新链表节点的创建,接下来需要将原始链表中的节点复制到新链表中。对于每一个原始链表中存在的节点,我们可以通过链表的遍历,通过node.next获取到其对应的新链表中的节点,并且为新链表中对应的节点设置随机指针指向,具体实现如下:

public static void connectSiblingNodes(ComplexListNode head) {
    ComplexListNode node = head;
    while (node != null) {
        ComplexListNode cloned = node.next;
        if (node.random != null) {
            cloned.random = node.random.next;
        }
        node = cloned.next;
    }
}

这里,我们首先复制了head节点,并将其赋值给node,接下来我们进行遍历,每次取出原始节点的下一个节点,并且将其赋值给cloned节点。如果原始节点存在random指针,那么我们需要将其指向的节点在新链表中的节点赋值给clonedrandom指针。

连接新旧链表

完成前两个步骤后,我们已经创建了与原始链表对应位置的新链表,并且为其连接了随机指针指向。接下来,我们需要将两个链表分开,并且返回只包含新链表的头结点。具体实现如下:

public static ComplexListNode reconnectNodes(ComplexListNode head) {
    ComplexListNode node = head;
    ComplexListNode clonedHead = null;
    ComplexListNode clonedNode = null;
    if (node != null) {
        clonedHead = clonedNode = node.next;
        node.next = clonedNode.next;
        node = node.next;
    }
    while (node != null) {
        clonedNode.next = node.next;
        clonedNode = clonedNode.next;
        node.next = clonedNode.next;
        node = node.next;
    }
    return clonedHead;
}

这里,我们首先取出原始链表中的第一个节点,并且根据第一步中新创建的节点,取出对应位置的新链表中的头结点,并将其赋值给clonedHeadclonedNode。接下来进行遍历,分别移动新旧链表中的指针,并将其连接起来。最后返回只包含新链表的头结点。

完整代码

将以上三步整合起来,我们得到完整的复制带随机指针链表的代码实现:

class ComplexListNode{
    int val;
    ComplexListNode next;
    ComplexListNode random;
    public ComplexListNode(int val) {
        this.val = val;
    }
}

public static ComplexListNode clone(ComplexListNode head) {
    cloneNodes(head);
    connectSiblingNodes(head);
    return reconnectNodes(head);
}

public static void cloneNodes(ComplexListNode head) {
    ComplexListNode node = head;
    while (node != null) {
        ComplexListNode cloned = new ComplexListNode(node.val);
        cloned.next = node.next;
        cloned.random = null;
        node.next = cloned;
        node = cloned.next;
    }
}

public static void connectSiblingNodes(ComplexListNode head) {
    ComplexListNode node = head;
    while (node != null) {
        ComplexListNode cloned = node.next;
        if (node.random != null) {
            cloned.random = node.random.next;
        }
        node = cloned.next;
    }
}

public static ComplexListNode reconnectNodes(ComplexListNode head) {
    ComplexListNode node = head;
    ComplexListNode clonedHead = null;
    ComplexListNode clonedNode = null;
    if (node != null) {
        clonedHead = clonedNode = node.next;
        node.next = clonedNode.next;
        node = node.next;
    }
    while (node != null) {
        clonedNode.next = node.next;
        clonedNode = clonedNode.next;
        node.next = clonedNode.next;
        node = node.next;
    }
    return clonedHead;
}

示例说明

假设我们有一个链表为:

1 -> 2 -> 3 -> null
|    |
V    V
2 -> 3

我们可以根据以上代码实现将其深拷贝,得到新的链表:

1 -> 2 -> 3 -> null
|    |
V    V
2 -> 3

其中新链表中的每个节点都与原始链表中对应,而且随机指针指向也正确。这里为了方便演示,我们只展示了一个示例。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java面试题-实现复杂链表的复制代码分享 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 新手架设魔兽单机和局域网服务器教程

    新手架设魔兽单机和局域网服务器教程 简介 本教程将会教授新手如何在本机上架设魔兽单机和局域网服务器的方法,包含了从下载所需文件到配置服务器参数的详细步骤。使用本教程前,您需要确认您的电脑符合以下要求: 操作系统为Windows XP或以上版本 CPU为Intel Pentium 4或AMD Athlon XP 2000+以上 内存不低于1GB 步骤 步骤1:…

    other 2023年6月27日
    00
  • 卸载gitlab

    卸载 GitLab 在使用 GitLab 进行项目管理的过程中,我们可能会需要卸载掉它。本文将介绍如何卸载 GitLab。 注意! 卸载 GitLab 将删除所有数据,如代码、问题、合并请求、评论等,所以请务必备份重要数据。 步骤一:停止 GitLab 首先需要停止 GitLab 服务: sudo gitlab-ctl stop 步骤二:卸载 GitLab …

    其他 2023年3月29日
    00
  • CentOS 7.2系统安装步骤

    以下是CentOS 7.2系统安装步骤的完整攻略,包括准备工作、安装步骤、示例说明和注意事项。 准备工作 以下是安装CentOS 7.2系统前需要准备的工作: 下载CentOS 7.2镜像:从CentOS官网下载CentOS 7.2镜像文件。 制作启动盘:使用制作启动盘工具,将CentOS 7.2镜像写入U盘或DVD。 准备安装设备:准备一台计算机或虚拟机,…

    other 2023年5月6日
    00
  • Creo直线怎么变成构造线? Creo中构造线的制作方法

    Creo直线变成构造线的方法 在Creo中,将直线转换为构造线是一种常见的操作。构造线是一种特殊类型的几何元素,用于辅助设计和约束模型。下面是将直线转换为构造线的详细步骤: 首先,打开Creo软件并加载您的模型。 选择直线:使用选择工具(通常是箭头图标),单击并选择您想要转换为构造线的直线。您可以使用鼠标拖动来选择直线。 右键单击选择的直线:在选择直线后,右…

    other 2023年8月6日
    00
  • mysql两个count求和

    MySQL两个Count求和 在数据统计中,Count函数是被广泛使用的一个函数。Count函数的作用是计算指定列的行数,从而得到统计结果。有时候,我们需要求两个Count结果的和,本文将介绍如何使用MySQL来实现这种求和操作。 1. 使用嵌套子查询 一种方法是使用嵌套子查询来实现这种求和操作。下面是示例代码: SELECT (SELECT COUNT(*…

    其他 2023年3月28日
    00
  • C语言memset函数详解

    C语言memset函数详解 在C语言中,涉及到对一段内存空间的清空或赋值操作时,可以使用memset函数。本文将对memset函数进行详细讲解。 函数定义 void *memset(void *s, int c, size_t n); 这里的参数含义是: s:需要进行清空或赋值操作的内存空间的首地址。 c:需要进行赋值的内容。由于参数类型是int,实际上只会…

    other 2023年6月27日
    00
  • PHP利用递归函数实现无限级分类的方法

    下面是详细讲解“PHP利用递归函数实现无限级分类的方法”的完整攻略。 什么是无限级分类? 在讲解实现方法之前,我们先解释一下什么是无限级分类。所谓无限级分类,就是指在一个分类系统中,每个分类下可以再嵌套多个子分类,子分类下又可以再嵌套子分类,以此类推,可以无限嵌套下去。 实现方法 实现无限级分类的方法有很多,这里我们以递归函数的方式进行讲解。具体实现步骤如下…

    other 2023年6月27日
    00
  • 怎样使用路由器手动更换ip地址?

    怎样使用路由器手动更换IP地址? 如果你想手动更换路由器的IP地址,下面是一个详细的攻略,包含了两个示例说明。 步骤1:登录路由器管理界面 首先,你需要登录到路由器的管理界面。打开你的网页浏览器,输入路由器的默认IP地址(通常是192.168.1.1或192.168.0.1)并按下回车键。这将打开路由器的登录页面。 步骤2:输入用户名和密码 在登录页面上,输…

    other 2023年7月30日
    00
合作推广
合作推广
分享本页
返回顶部