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

yizhihongxing

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日

相关文章

  • 原创的C语言控制台小游戏

    原创的C语言控制台小游戏攻略 简介 本游戏是一款用C语言编写的控制台小游戏。玩家需要通过控制方向键,使得主角躲避障碍物,并尽可能多的吃到食物来获得高分。游戏中还设置了特殊障碍物和加速道具,玩家需一定技巧才能获得高分。 游戏规则 游戏场景是一个矩形,玩家需要通过控制主角,躲避上下左右移动的障碍物和随机出现的特殊障碍物。 玩家通过控制方向键控制主角向上、向下、向…

    other 2023年6月27日
    00
  • ernie(二妮儿)模型初探

    以下是关于“ERNIE(二妮儿)模型初探”的完整攻略,包括ERNIE模型的定义、原理、训练方法、应用场景和两个示例说明。 ERNIE模型的定义 ERNIE(Enhanced Representation through kNowledge IntEgration)是百度推出的一种基于知识增强的预训练语言模型。ERNIE模型在BERT模型的基础上,通过引入实体…

    other 2023年5月7日
    00
  • Java处理表格的实用工具库

    Java处理表格的实用工具库 在Java开发中,有许多实用的工具库可用于处理表格数据。以下是使用两个常用的Java表格处理工具库的详细攻略: Apache POI Apache POI是一个流行的Java库,用于读取、写入和操作Microsoft Office格式的文件,包括Excel表格。以下是使用Apache POI处理表格的示例说明: 首先,确保已经添…

    other 2023年10月15日
    00
  • 电脑应该装32位还是64位系统?

    电脑应该装32位还是64位系统? 选择电脑操作系统的位数是一个重要的决策,它会直接影响到电脑的性能和兼容性。在选择之前,我们需要了解32位和64位系统的区别以及它们的优缺点。 32位系统 32位系统是较早的操作系统版本,它可以在32位处理器和64位处理器上运行。以下是32位系统的一些特点: 内存限制: 32位系统最大支持4GB的内存。这意味着,如果你的电脑有…

    other 2023年7月28日
    00
  • MySQL字符编码设置方法

    MySQL字符编码设置方法 字符编码(Character Encoding)在数据库中是一个非常重要的配置项。它负责将实际存储在数据库中的二进制数据(如字符串)转换为可读的文本形式,并且也能决定如何存储和比较文本。 MySQL支持多种字符编码,包括Unicode、ASCII、UTF8等。正确设置MySQL字符编码是确保数据在数据库中正确存储和显示的关键。在下…

    other 2023年6月25日
    00
  • tortoisesvn版本合并(merge)

    TortoiseSVN版本合并(Merge) TortoiseSVN是一个Subversion版本控制系统的Windows客户端。它使用户可以浏览Subversion仓库,检出元数据,并执行更改以发布新代码。TortoiseSVN的一个主要功能是版本合并,也称为Merge。 什么是版本合并? 版本合并是将不同版本的代码或文档的更改合并为一个新版本的过程。版本…

    其他 2023年3月28日
    00
  • idea部署nodejs项目

    IDEA部署NodeJS项目 在这篇文章中,我们将介绍如何在IntelliJ IDEA上部署Node.js项目。 什么是Node.js? Node.js是基于Chrome V8 JavaScript引擎构建的JavaScript运行时。它允许开发者使用JavaScript编写服务器端代码,并使用同一种语言编写客户端和服务器端代码。Node.js带来了许多好处…

    其他 2023年3月28日
    00
  • 如何实现bean初始化摧毁方法的注入

    实现bean初始化摧毁方法的注入,需要通过Spring的IOC容器实现。Spring提供了两种方式来实现bean的初始化和销毁方法的注入:使用注解和使用XML配置文件。 一、使用注解的方式: 使用注解@PostConstruct来指定bean初始化方法,使用@PreDestroy来指定bean销毁方法。 @Component public class MyB…

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