LeetCode题练习与总结:随机链表的复制--138

news2024/10/10 2:22:49

一、题目描述

给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。

构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 

例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。

返回复制链表的头节点。

用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

  • val:一个表示 Node.val 的整数。
  • random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为  null 。

你的代码  接受原链表的头节点 head 作为传入参数。

示例 1:

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

示例 2:

输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]

示例 3:

输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]

提示:

  • 0 <= n <= 1000
  • -10^4 <= Node.val <= 10^4
  • Node.random 为 null 或指向链表中的节点。

二、解题思路

  1. 复制每个节点:遍历原始链表,对于每个节点创建其副本,并将副本插入到原节点和下一个节点之间。比如,原始链表是 A -> B -> C,则变为 A -> A’ -> B -> B’ -> C -> C’,其中 A’, B’, C’ 是对应 A, B, C 的副本。

  2. 复制随机指针:再次遍历链表,这次设置每个副本节点的random指针。由于副本节点紧跟在原节点之后,可以通过原节点的random指针找到对应的副本节点。

  3. 拆分链表:最后,将原始链表和复制链表分离。保持原链表不变,并返回复制链表的头节点。

三、具体代码

class Solution {
    public Node copyRandomList(Node head) {
        if (head == null) return null;

        // Step 1: Copy each node and insert it to the list
        Node current = head;
        while (current != null) {
            Node newNode = new Node(current.val);
            newNode.next = current.next;
            current.next = newNode;
            current = newNode.next;
        }

        // Step 2: Copy random pointers for each copied node
        current = head;
        while (current != null) {
            if (current.random != null) {
                current.next.random = current.random.next;
            }
            current = current.next.next;
        }

        // Step 3: Separate the copied list from the original list
        Node dummy = new Node(0);
        Node copy = dummy;
        current = head;
        while (current != null) {
            copy.next = current.next;
            copy = copy.next;
            current.next = copy.next;
            current = current.next;
        }

        return dummy.next;
    }
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 复制每个节点:这一步需要遍历整个链表一次,时间复杂度为 O(n),其中 n 是链表中的节点数。

  • 复制随机指针:这一步同样需要遍历整个链表一次,时间复杂度也是 O(n)。

  • 拆分链表:这一步同样需要遍历整个链表一次,时间复杂度为 O(n)。

  • 综合以上步骤,总的时间复杂度是 O(n) + O(n) + O(n) = O(n)。

2. 空间复杂度
  • 复制每个节点:这一步为每个节点创建了一个新的副本节点,因此需要额外的空间来存储这些节点。由于新节点的数量与原链表的节点数相同,所以空间复杂度为 O(n)。

  • 复制随机指针:这一步没有使用额外的空间,只是修改了节点之间的指针。

  • 拆分链表:这一步也没有使用额外的空间,只是重新排列了节点之间的指针。

  • 综合以上步骤,总的空间复杂度是 O(n)。

这里的时间复杂度和空间复杂度都是基于链表的长度来计算的。时间复杂度是线性的,因为我们只需要遍历链表几次,每次都是线性时间。空间复杂度也是线性的,因为我们创建了一个与原链表长度相同的复制链表。

五、总结知识点

  1. 链表操作:代码中涉及了链表的遍历、节点的创建、节点间关系的修改(包括nextrandom指针)以及链表的拆分。

  2. 指针操作:代码中使用了多个指针来遍历和修改链表。例如,current指针用于遍历原始链表,newNode用于创建新节点,copydummy用于构建复制链表。

  3. 递归与迭代:虽然代码中没有直接使用递归,但它使用了迭代的方式来遍历链表。迭代是处理链表问题的一种常见方法。

  4. 边界条件处理:代码中首先检查了链表为空的情况,并进行了相应的处理,这是一种常见的边界条件检查。

  5. 链表拼接:在第一步中,代码将新创建的节点插入到原始链表中,这是链表拼接的一种形式。

  6. 链表拆分:在第三步中,代码将复制后的链表从原始链表中分离出来,这是链表拆分的一个例子。

  7. 虚拟头节点(Dummy Node)的使用:代码中使用了虚拟头节点dummy来简化链表操作,特别是在构建新的链表时。虚拟头节点通常在处理链表问题时非常有用,因为它可以避免处理头节点的特殊情况。

  8. 链表深拷贝:整个代码的目的是实现链表的深拷贝,这是一种常见的编程技巧,用于创建一个独立于原始链表的新链表。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1863066.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

成功解决ES高亮内容引起的字段显示不一致问题

在处理搜索引擎&#xff08;如Elasticsearch&#xff09;结果时&#xff0c;常见需求之一是对用户搜索的关键词进行高亮显示&#xff0c;这有助于用户快速识别搜索结果为何与其查询相关。但在实际应用中&#xff0c;如果处理不当&#xff0c;直接使用高亮片段可能会导致原始数据…

冰淇淋PDF编辑器,轻量,无需安装,打开即用

​IceCream PDF Editor (冰淇淋PDF编辑器) 是一款简单实用的PDF文件编辑工具。功能包括&#xff1a;编辑文本、注释添加、页面管理、PDF文件保护等&#xff1b;操作简单&#xff0c;功能强大&#xff0c;使用户能够轻松编辑和修改PDF文件。 软件链接&#xff1a;轻量&#xff…

代码随想录算法训练营第四十五天| 198.打家劫舍,213.打家劫舍II ,337.打家劫舍III

198. 打家劫舍 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int rob(int[] nums) {int[] dp new int[nums.length];if(nums.length 1){return nums[0];}dp[0] nums[0];dp[1] Math.max(nums[0],nums[1]);for(int i2;i<nums.length;i){dp[i] Math.ma…

【服务器】磁盘满载--docker 的日志文件太大造成满载

一.背景 早上过来测试反馈服务器都宕机了,访问不了。一看服务器磁盘都已经满了。所以开始清磁盘数据。 二.解决 主要查看下面目录情况: /home/libe/docker /containers /volumes /overlay21.查看磁盘情况 df -h/ du -a|sort -rn|…

国密SSL证书提升网络安全

随着数字化时代的到来&#xff0c;网络安全已经成为全球关注的焦点。在这种背景下&#xff0c;SSL证书作为保护数据传输安全的重要工具&#xff0c;其重要性日益凸显。 数字证书产品有以下几种类别&#xff1a; 单域名SSL证书&#xff1a;为单一网站提供安全保护。 多域名SS…

ICMAN液位检测——WS003B管道检测模组

ICMAN液位检测之WS003B管道检测模组 体积小&#xff0c;成本低&#xff0c; 液位检测精度高&#xff0c; 有水输出低电平无水高电平&#xff0c; 适用于饮水机、咖啡机、扫地机器人、洗地机等&#xff0c; 有需要朋友快联系我吧&#xff01; AWE展会不容错过的ICMAN检测模组…

sheng的学习笔记-AI-高斯混合模型(GMM)

AI目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 sheng的学习笔记-AI-聚类(Clustering)-CSDN博客需要学习前置知识&#xff1a; 聚类&#xff0c;可参考 sheng的学习笔记-AI-聚类(Clustering)-CSDN博客 EM算法&#xff0c;可参考 sheng的学习笔记-AI-EM算法-CSDN博客 贝…

python编写的多个FastApi接口如何批量运行

fastapi编写接口并批量运行 为什么要写这fastapi接口以及拿它做什么呢&#xff1f; fastapi可以快速构建你自己的api&#xff0c;前端后端联调时&#xff0c;后端接口还有做好&#xff0c;那么这个fastapi可以快速生成mock一些数据。 结合uvicorn这个python库使用起来很方便 为…

【Python实战因果推断】1_因果效应异质性1

目录 From ATE to CATE Why Prediction Is Not the Answer CATE and ITE 本文将介绍应用于行业的因果推理中最有趣的发展&#xff1a;效应异质性。在此之前&#xff0c;你们了解的是一种治疗方法的一般影响。现在&#xff0c;你将专注于发现它如何对不同的人产生不同的影响。…

【漏洞复现】用友 UFIDA saveDoc.ajax 任意文件上传漏洞

免责声明&#xff1a; 本文内容旨在提供有关特定漏洞或安全漏洞的信息&#xff0c;以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步&#xff0c;并非出于任何恶意目的。阅读者应该明白&#xff0c;在利用本文提到的漏洞信息或进行相关测…

web前端大作业-乡村扶贫、乡村振兴

文章目录 代码分析页面截图代码连接 代码分析 代码结构 主页index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta…

基于RabbitMQ原理的自定义消息队列实现

文章目录 1. 什么是消息队列2. 需求分析2.1. 核心概念12.2. 核心概念22.3. 核心API2.4. 交换机类型2.5. 持久化2.6. 网络通信2.7. 总结 3. 创建核心类3.1. Exchange3.2. MSGQueue3.3. Binding3.4. Message3.5. 数据库操作3.5.1. 建表操作3.5.2. 交换机操作3.5.3. 队列操作3.5.4…

力扣62 不同路径

一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#xff1f; 输入&…

智能终端-Qt-课程设计分析

这个是几个简单的Qt的智能终端分享&#xff0c;其是我们上课的作业&#xff0c;我就在老师要求的基础上去进行了延申了一点的&#xff0c;下面看做了哪些东西 这个是所有的点开之后的页面&#xff0c;我做到了那些家居和那个按钮达到了同步的效果&#xff0c;这点其实还是不错…

仿真模拟--静态浮动路由

目录 静态路由 浮动路由 静态路由 浮动路由

Linux CentOS 环境 MySQL 主从复制集群搭建

环境说明 MySQL版本8.4.0 操作系统 Linux CentOS 7.9 官网文档 https://dev.mysql.com/doc/refman/8.4/en/replication-configuration.html 以下代码片段中带分号都是在MySQL命令行( mysql -uroot -p)中执行 1. 首先在两个节点上安装数据库 参考 Linux CentOS安装MySQL8.0 …

如何把图片转换成pdf格式?图片转PDF方法分享

如何把图片转换成pdf格式&#xff1f;图片转换为PDF格式的重要性不言而喻。PDF文件不仅能够在各种操作系统和设备上保持一致的显示效果&#xff0c;还能确保图片内容的清晰度和质量不受损害。此外&#xff0c;PDF格式支持加密和权限设置&#xff0c;可以保护图片内容不被轻易篡…

C#——SortedList 排序列表详情

SortedList 排序列表 SortedList 类用来表示键/值对的集合&#xff0c;这些键/值对按照键值进行排序&#xff0c;并且可以通过键或索引访问集合中的各个项。 我们可以将排序列表看作是数组和哈希表的组合&#xff0c;其中包含了可以使用键或索引访问各项的列表。如果您使用索…

centOS 7安装gitlab

主要参考&#xff1a; CentOS-7 下 GitLab 安装部署教程_centos7 安装gitlab-CSDN博客 但是由于我本身服务器配置很小(2核2G)&#xff0c;所以运行的时候报错&#xff1a; execute[clear the gitlab-rails cache] (gitlab::gitlab-rails line 561) had an error: Mixlib::Sh…

【Linux】静态库、动态库

动静态库里面包含的是源文件通过汇编阶段生成的后缀为.o的可重定位目标文件。我们在使用C语言&#xff0c;包含一个stdio.h头文件就可以使用scanf方法&#xff0c;其实都是系统调用了相应的头文件和库&#xff0c;库里面有开发者已经写好各种方法。也就是说我们在使用C语言时&a…