随机链表的复制[中等]

news2025/1/17 1:24:45

优质博文:IT-BLOG-CN

一、题目

给你一个长度为n的链表,每个节点包含一个额外增加的随机指针random,该指针可以指向链表中的任何节点或空节点。构造这个链表的深拷贝。深拷贝应该正好由n个全新节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的next指针和random指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点。

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

用一个由n个节点组成的链表来表示输入/输出中的链表。每个节点用一个[val, random_index]表示:
【1】val:一个表示Node.val的整数。
【2】random_index:随机指针指向的节点索引(范围从0n-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
-104 <= Node.val <= 104
Node.randomnull或指向链表中的节点。

二、代码

【1】回溯 + 哈希表: 本题要求我们对一个特殊的链表进行深拷贝。如果是普通链表,我们可以直接按照遍历的顺序创建链表节点。而本题中因为随机指针的存在,当我们拷贝节点时,「当前节点的随机指针指向的节点」可能还没创建,因此我们需要变换思路。一个可行方案是,我们利用回溯的方式,让每个节点的拷贝操作相互独立。对于当前节点,我们首先要进行拷贝,然后我们进行「当前节点的后继节点」和「当前节点的随机指针指向的节点」拷贝,拷贝完成后将创建的新节点的指针返回,即可完成当前节点的两指针的赋值。

具体地,我们用哈希表记录每一个节点对应新节点的创建情况。遍历该链表的过程中,我们检查「当前节点的后继节点」和「当前节点的随机指针指向的节点」的创建情况。如果这两个节点中的任何一个节点的新节点没有被创建,我们都立刻递归地进行创建。当我们拷贝完成,回溯到当前层时,我们即可完成当前节点的指针赋值。注意一个节点可能被多个其他节点指向,因此我们可能递归地多次尝试拷贝某个节点,为了防止重复拷贝,我们需要首先检查当前节点是否被拷贝过,如果已经拷贝过,我们可以直接从哈希表中取出拷贝后的节点的指针并返回即可。

在实际代码中,我们需要特别判断给定节点为空节点的情况。

class Solution {
    Map<Node, Node> cachedNode = new HashMap<Node, Node>();

    public Node copyRandomList(Node head) {
        if (head == null) {
            return null;
        }
        if (!cachedNode.containsKey(head)) {
            Node headNew = new Node(head.val);
            cachedNode.put(head, headNew);
            headNew.next = copyRandomList(head.next);
            headNew.random = copyRandomList(head.random);
        }
        return cachedNode.get(head);
    }
}

时间复杂度: O(n),其中n是链表的长度。对于每个节点,我们至多访问其「后继节点」和「随机指针指向的节点」各一次,均摊每个点至多被访问两次。
空间复杂度: O(n),其中n是链表的长度。为哈希表的空间开销。

【2】迭代 + 节点拆分: 注意到方法一需要使用哈希表记录每一个节点对应新节点的创建情况,而我们可以使用一个小技巧来省去哈希表的空间。

我们首先将该链表中每一个节点拆分为两个相连的节点,例如对于链表A→B→C,我们可以将其拆分为A→A′→B→B′→C→C′。对于任意一个原节点S,其拷贝节点S′即为其后继节点。这样,我们可以直接找到每一个拷贝节点S′的随机指针应当指向的节点,即为其原节点S的随机指针指向的节点T的后继节点T′。需要注意原节点的随机指针可能为空,我们需要特别判断这种情况。

当我们完成了拷贝节点的随机指针的赋值,我们只需要将这个链表按照原节点与拷贝节点的种类进行拆分即可,只需要遍历一次。同样需要注意最后一个拷贝节点的后继节点为空,我们需要特别判断这种情况。

class Solution {
    public Node copyRandomList(Node head) {
        if (head == null) {
            return null;
        }
        for (Node node = head; node != null; node = node.next.next) {
            Node nodeNew = new Node(node.val);
            nodeNew.next = node.next;
            node.next = nodeNew;
        }
        for (Node node = head; node != null; node = node.next.next) {
            Node nodeNew = node.next;
            nodeNew.random = (node.random != null) ? node.random.next : null;
        }
        Node headNew = head.next;
        for (Node node = head; node != null; node = node.next) {
            Node nodeNew = node.next;
            node.next = node.next.next;
            nodeNew.next = (nodeNew.next != null) ? nodeNew.next.next : null;
        }
        return headNew;
    }
}

时间复杂度: O(n),其中n是链表的长度。我们只需要遍历该链表三次。读者们也可以自行尝试在计算拷贝节点的随机指针的同时计算其后继指针,这样只需要遍历两次。
空间复杂度: O(1)。注意返回值不计入空间复杂度。

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

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

相关文章

【论文笔记】A Transformer-based Approach for Source Code Summarization

A Transformer-based Approach for Source Code Summarization 1. Introduction2. Approach2.1 ArchitectureSelf-AttentionCopy Attention 2.2 Position Representations编码绝对位置编码成对关系 1. Introduction 生成描述程序功能的可读摘要称为源代码摘要。在此任务中&…

C++ day55 判断子序列 不同的子序列

题目1&#xff1a;392 判断子序列 题目链接&#xff1a;判断子序列 对题目的理解 判断字符串s是否为t的子序列 字符串s和字符串t的长度大于等于0&#xff0c;字符串s的长度小于等于字符串t的长度&#xff0c;本题其实和最长公共子序列的那道题很相似&#xff0c;相当于找两…

面试就是这么简单,offer拿到手软(四)—— 常见java152道基础面试题

面试就是这么简单&#xff0c;offer拿到手软&#xff08;一&#xff09;—— 常见非技术问题回答思路 面试就是这么简单&#xff0c;offer拿到手软&#xff08;二&#xff09;—— 常见65道非技术面试问题 面试就是这么简单&#xff0c;offer拿到手软&#xff08;三&#xff…

【数据结构(七)】查找算法

文章目录 查找算法介绍1. 线性查找算法2. 二分查找算法2.1. 思路分析2.2. 代码实现2.3. 功能拓展 3. 插值查找算法3.1. 前言3.2. 相关概念3.3. 实例应用 4. 斐波那契(黄金分割法)查找算法4.1. 斐波那契(黄金分割法)原理4.2. 实例应用 查找算法介绍 在 java 中&#xff0c;我们…

【Midjourney实战】| 新年礼盒元素设计

文章目录 1 初步提示词2 润色提示词3 提示词发散联想 这期实践任务&#xff0c;我们想去做一个新年礼盒的效果&#xff0c;最后我们想把不同元素拼在一起&#xff0c;方便后期进行新年的相关设计 1 初步提示词 提示词初步我们乍一想&#xff0c;肯定要包括主体元素礼盒 新年礼…

APOLLO自动驾驶技术沙龙:未来已来,共创智能交通新时代

在这次Apollo会议上&#xff0c;我深刻地感受到了人工智能自动驾驶技术领域的最新进展和未来趋势。作为一名从事软件开发工作的人员&#xff0c;我深感荣幸能够参加这次盛会。 前言 本次活动是百度Apollo社区工程师齐聚首钢Park&#xff0c;带来现场实操与技术分享。主要围绕Ap…

好用的挂耳式蓝牙耳机有哪些?四款好用高性价比的耳机推荐

随着生活节奏的加快&#xff0c;挂耳式蓝牙耳机真的是越来越不可或缺了&#xff0c;不管是坐地铁、步行还是运动&#xff0c;一副好用的挂耳式蓝牙耳机都能让你感觉自己像是生活里的主角。但市面上的选择实在是太多了&#xff0c;简直让人眼花缭乱&#xff0c;不过我找了四款真…

仓库管理系统【GUI/Swing+MySQL】(Java课设)

系统类型 Swing窗口类型Mysql数据库存储数据 使用范围 适合作为Java课设&#xff01;&#xff01;&#xff01; 部署环境 jdk1.8Mysql8.0Idea或eclipsejdbc 运行效果 本系统源码地址&#xff1a; 更多系统资源库地址&#xff1a;更多Java课设系统 更多系统运行效果展示…

很全面 影响无人机自动返航的因素总结

在无人机技术不断成熟的今天&#xff0c;自主返航技术成为保障飞行安全的一种重要工具。无人机在多种情况下能够智能判断&#xff0c;主动实施返航动作&#xff0c;为用户提供更加可靠的飞行保障。以下是一些常见的无人机自动返航场景&#xff0c;让我们深入了解这项技术背后的…

玩转数据8:数据质量管理与数据清洗的实践

引言 在当今数字化时代&#xff0c;数据质量管理和数据清洗对于企业和组织来说变得至关重要。随着大数据的快速增长和数据驱动决策的普及&#xff0c;确保数据的准确性、一致性和完整性成为保证业务成功的关键因素。本文将探讨数据质量管理和数据清洗的概念、目标以及其在Java…

U-Net网络模型改进(添加通道与空间注意力机制)---亲测有效,指标提升

U-Net网络模型&#xff08;注意力改进版本&#xff09; 这一段时间做项目用到了U-Net网络模型&#xff0c;但是原始的U-Net网络还有很大的改良空间&#xff0c;在卷积下采样的过程中加入了通道注意力和空间注意力 。 常规的U-net模型如下图&#xff1a; 红色箭头为可以添加的…

电表峰谷平是怎么分时间的?

电表的峰谷平时间是指电力公司根据电力需求的不同&#xff0c;将一天的时间划分为不同的时段&#xff0c;以此来确定不同时间段内的电费价格。这种不同时段对应不同电费价格的制度&#xff0c;旨在更好地平衡电力供需&#xff0c;促进能源的高效利用。 首先&#xff0c;我们来了…

记录一下Mac配置SpringBoot开发环境

由于很多项目喜欢使用传统的 Java 8 进行开发&#xff0c;而且 Java 8 的稳定性也是经过长久考验的&#xff0c;我们接下来就尝试一下&#xff0c;在一台新的 Mac 中配置 Java 环境&#xff0c;并且开始创建 SpringBoot 项目。 首先&#xff0c;去 Oracle 官网下载 java8 JDK …

springboot详解Mybatis-Plus中分页插件PaginationInterceptor标红

1.问题描述 在springboot项目中&#xff0c;类中引用PaginationInterceptor&#xff0c;标红&#xff0c;如下图所示&#xff1a; 2.问题分析 可能是因为pom.xml中的配置原因&#xff0c;导致不支持PaginationInterceptor 3.解决问题 更换版本后 更换后&#xff0c;记得Rel…

开发的客户收到样品表示质量不如原供应商如何应对

有小伙伴问&#xff0c;在开发客户的过程当中&#xff0c;给客户寄了样品&#xff0c;客户说他的样品没有原来供应商的好怎么办&#xff1f; 这个问题我们来想一下&#xff0c;客户既然愿意把地址给我们&#xff0c;愿意去接你的样品&#xff0c;说明什么&#xff1f;说明客户…

【剑指offer|图解|位运算】训练计划VI+撞色搭配

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;数据结构、剑指offer每日一练 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️训练计划VI&#xff08;题目难度&#xff1a;中等&#xff09;1.1 题目1.2 示例1.3 …

2024年猫罐头排行榜前十名有哪些?分享2024年猫罐头排行榜前10名

很多人家里的哈基米是不是吃猫粮吃腻了&#xff0c;或者猫猫平时不喜欢喝水&#xff0c;又或者看猫猫太瘦了想入手几款猫罐头但是又愁于不会选择。而且现在猫罐头风这么大不知道选什么好~ 作为从业5年的宠物医生&#xff0c;给你说猫罐头行业内幕。我告诫大家&#xff0c;选择…

Python网络爬虫环境的安装指南

网络爬虫是一种自动化的网页数据抓取技术&#xff0c;广泛用于数据挖掘、信息搜集和互联网研究等领域。Python作为一种强大的编程语言&#xff0c;拥有丰富的库支持网络爬虫的开发。本文将为你详细介绍如何在你的计算机上安装Python网络爬虫环境。 一、安装python开发环境 进…

SIT75179B,5V 供电, 10Mbps,全双工差分芯片/全双工 RS485/RS422 收发器

SIT75179B 是一款 4.5V~5.5V 供电全双工差分芯片&#xff0c;可完全满足 TIA/EIA-485/422 标准要求 的收发器。 SIT75179B 包括一个驱动器和一个接收器&#xff0c;两者均可独立传输信号。 SIT75179B 具有 1/8 负 载&#xff0c;允许 256 个 SIT75179B 收发器并…

【AIGC】AI作图最全提示词prompt集合(收藏级)

目录 一、正向和负向提示词 二、作图参数 你好&#xff0c;我是giszz. AI做图真是太爽了&#xff0c;解放生产力&#xff0c;发展生产力。 但是&#xff0c;你是不是也总疑惑&#xff0c;为什么别人的图&#xff0c;表现力那么丰富呢&#xff0c;而且指哪打哪&#xff0c;要…