java算法题解LeetCode35复杂链表的复制实例

Java算法题解LeetCode35复杂链表的复制实例

题目描述

给定一个链表,除了正常的next指针外,还有一个额外的指针random指向链表中的任意一个节点或者null。请返回这个链表的深度复制。

例如,给定链表1->2->3->4->null,random指针可能指向链表中的任意一个节点,也可能指向null。

解题思路

方法一:哈希表

一个比较暴力的做法是使用哈希表来保存原链表节点和新链表节点之间的对应关系。具体来说,对于原链表中的每个节点,我们创新一个新的节点,并存储在哈希表中,然后我们再次遍历链表,在遍历的过程中处理每个新节点的 next 和 random 指针。

步骤如下:

  1. 遍历链表,将其中的每个节点都存入哈希表中。
  2. 再次遍历链表,对于每个新节点,根据原链表中对应节点的下标,设置新节点的 next 指针和 random 指针。

时间复杂度为O(N),其中N是链表中节点的数量。需要额外的空间来存储哈希表,空间复杂度也为O(N)。

public Node copyRandomList(Node head) {
    if (head == null) {
        return null;
    }
    Map<Node, Node> map = new HashMap<>();
    Node newHead = new Node(head.val);
    map.put(head, newHead);
    Node p = head;
    Node q = newHead;
    while (p != null) {
        if (p.next != null) {
            if (!map.containsKey(p.next)) {
                Node newNode = new Node(p.next.val);
                map.put(p.next, newNode);
            }
            q.next = map.get(p.next);
        }
        if (p.random != null) {
            if (!map.containsKey(p.random)) {
                Node newNode = new Node(p.random.val);
                map.put(p.random, newNode);
            }
            q.random = map.get(p.random);
        }
        p = p.next;
        q = q.next;
    }
    return newHead;
}

方法二:原地修改链表

思路是先遍历原链表,对于其中的每一个节点都创建一个新的节点,并将新节点连接到原节点后面。然后再次遍历链表,通过分析原节点的random指针和新节点的next指针的关系,来设置新节点的random指针。

步骤如下:

  1. 遍历链表,对于每一个节点,在该节点之后插入该节点的复制节点。

    原链表:1 -> 2 -> 3
    新链表:1 -> 1' -> 2 -> 2' -> 3 -> 3'

  2. 再次遍历链表,根据原节点的random指针修改新节点的random指针。

    ```
    原链表中的random指针:
    1 -> 3
    2 -> 1
    3 -> 2

    新链表中的random指针:
    1' -> 3'
    2' -> 1'
    3' -> 2'
    ```

  3. 将新链表和原链表分离。

    新链表:1' -> 2' -> 3'
    原链表:1 -> 2 -> 3

时间复杂度为O(N),空间复杂度为O(1)。

public Node copyRandomList(Node head) {
    if (head == null) {
        return null;
    }
    Node p = head;
    while (p != null) {
        Node newNode = new Node(p.val);
        newNode.next = p.next;
        p.next = newNode;
        p = newNode.next;
    }
    p = head;
    while (p != null) {
        Node newNode = p.next;
        if (p.random != null) {
            newNode.random = p.random.next;
        }
        p = newNode.next;
    }
    p = head;
    Node newHead = head.next;
    while (p != null) {
        Node newNode = p.next;
        p.next = newNode.next;
        if (newNode.next != null) {
            newNode.next = newNode.next.next;
        }
        p = p.next;
    }
    return newHead;
}

示例说明

示例一

输入:1 -> 2 -> null

1 -> null
^
|
2 -> null

输出:1 -> 2 -> null

1 -> null
^
|
2 -> null

示例二

输入:2 -> 1 -> null

2 -> null
^
|
1 -> null

输出:2 -> 1 -> null

2 -> null
^
|
1 -> null

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java算法题解LeetCode35复杂链表的复制实例 - Python技术站

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

相关文章

  • cookie的domain

    当然,我很乐意为您提供有关“cookie的domain”的完整攻略。以下是详细的步骤和两个示例: 1. 什么是cookie的domain? 在Web开发中,cookie是一种存储在用户计算机上的小文件,用于跟踪用户的活动和存储用户的偏好设置。cookie的domain是指cookie所属的域名。当浏览器向服务器发送请求时,它会将cookie发送到与请求匹配的…

    other 2023年5月6日
    00
  • Spring 整合多个配置文件的方法

    Spring框架支持将多个配置文件整合到一起,以便于管理和维护。下面是 Spring 整合多个配置文件的方法的完整攻略。 一、使用 import 标签方式整合多个配置文件 使用 import 标签将多个配置文件整合到一起的方式是比较常见的,它可以通过 Spring 配置文件的方式引用其他配置文件,从而实现整合。 示例1: 假设有一个名为 applicatio…

    other 2023年6月25日
    00
  • 用Python制作灯光秀短视频的思路详解

    用Python制作灯光秀短视频的思路详解 简介 灯光秀短视频是一种通过控制灯光的亮灭和颜色变化来展示特定图案或效果的视频。在Python中,我们可以利用一些库和工具来实现这个目标。下面是一个详细的攻略,介绍了制作灯光秀短视频的完整思路和过程。 步骤 步骤一:安装所需库和工具 首先,我们需要安装一些Python库和工具来帮助我们制作灯光秀短视频。以下是一些常用…

    other 2023年7月29日
    00
  • Mysql大小写敏感的问题

    MySQL大小写敏感的问题攻略 MySQL是一个常用的关系型数据库管理系统,它在处理大小写时有一些敏感性。本攻略将详细讲解MySQL大小写敏感的问题,并提供两个示例说明。 1. MySQL的大小写敏感性 MySQL在处理标识符(如表名、列名、变量名等)时,根据配置的不同,可能会对大小写敏感或不敏感。这取决于以下两个因素: 操作系统:在某些操作系统上,文件系统…

    other 2023年8月15日
    00
  • Fedora 9官方最终稳定版下载地址集合

    Fedora 9官方最终稳定版下载地址集合攻略 Fedora 9是一款流行的Linux发行版,本攻略将为您提供Fedora 9官方最终稳定版的下载地址集合。请按照以下步骤进行操作: 步骤一:访问Fedora官方网站 首先,您需要访问Fedora官方网站以获取Fedora 9的下载地址。您可以在浏览器中输入以下网址进行访问: https://getfedora…

    other 2023年8月4日
    00
  • 赌你会懵的C语言指针进阶数组场景解析

    下面我来详细讲解“赌你会懵的C语言指针进阶数组场景解析”的完整攻略。 概述 在C语言中,数组是非常常用的数据类型。但是对于数组的理解,不仅要理解数组的基本概念,还要深入理解数组和指针的关系。本文将通过两条示例来解析C语言指针进阶数组场景,并教会你如何正确地理解和使用指针和数组。 示例1:指针数组 假设我们有一个学生结构体,并且需要定义一个数组来存储多个学生的…

    other 2023年6月25日
    00
  • 苹果iOS9.3.2 Beta2开发者预览版发布:修复游戏中心Bug

    苹果iOS9.3.2 Beta2开发者预览版发布:修复游戏中心Bug 什么是iOS9.3.2 Beta2 iOS9.3.2 Beta2是苹果公司开发的操作系统的测试版,旨在让开发者们先行体验系统中新增的功能和修改的问题,以便他们在正式版发布前,为用户提供更好的体验。本次Beta2主要是修复了游戏中心的问题,下面详细介绍。 Beta2修复了哪些游戏中心的问题?…

    other 2023年6月26日
    00
  • 惠普M436打印机怎么重启? 打印机重启的教程

    惠普M436打印机重启教程 1.为什么要重启惠普M436打印机? 在使用惠普M436打印机时,有时会遇到打印机出现各种问题的情况,比如打印机卡纸、打印质量不佳等。此时,我们可以首先尝试重启打印机,这通常可以解决一些简单的技术问题。 2.惠普M436打印机的重启方法 以下是重启惠普M436打印机的步骤: 步骤1:按下电源按钮 首先,让我们找到位于惠普M436打…

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