链表:常见面试题-拷贝特殊链表

news2024/11/14 18:56:53

题目:

一种特殊的单链表节点类描述如下:

class Node {

        int value;

        Node next;

        Node rand;

        Node(int val) {value = val}

}

rand指针是单链表节点结构中新增的指针,rand可能指向链表中的任意一个节点(包括自己),也可能指向null.

给定一个由Node节点类型组成的无环单链表的头结点head,请实现一个函数完成复制这个链表,并返回新链表的头结点。

要求:时间复杂度O(N),额外空间复杂度O(1)

思路:这个题仍然有两种解法:利用额外容器或者使用有限几个变量,具体思路:

(1)使用额外的容器,使用一个HashMap,把当前链表的每一个Node作为key装入HashMap,value是它的拷贝节点,都装完之后依次取出每一个Node,把value(拷贝节点)的next和random分别指向HashMap中取出的以当前节点的next和random为key的拷贝节点,没有

(2)不使用额外的容器,只使用有限几个变量,先遍历链表,依次拷贝Node然后把拷贝节点放在当前当前节点和原来的next中间。 然后依次遍历链表,设置各个拷贝节点的random指针指向。最后把两个链表进行拆分.

第一种方法面试没有分且笔试的空间复杂度为O(N),笔试也过不了,这里我们不做介绍,有兴趣的可以自己写写玩。

第二种方法的拆分示意图:

对应的代码如下:

package dataStructure.linkedList.practice;

import dataStructure.linkedList.ListNodeWithRandom;

public class CopyLinkedListWithRandom {
    public static ListNodeWithRandom copyLinkedList(ListNodeWithRandom head) {
        if(head == null) return head;
        ListNodeWithRandom cur = head;
        ListNodeWithRandom next = null;
        //把每个节点复制一个放在当前节点和当前节点的next之间,最后一个copy放在当前节点和null之间
        //例如1->2->3变成1->11->2->22->3->33
        while(cur != null) {
            next = cur.next;
            cur.next = new ListNodeWithRandom(cur.val, cur.name+"'");
            cur.next.next = next;
            cur = next;
        }

        cur = head;
        //设置random指针
        while(cur != null) {
            //取到当前Node的random指针
            ListNodeWithRandom random = cur.random;
            //当前random如果为空,那拷贝节点的random也应该为空
            //如果当前random不为空,则random的下一个(原链表中random的拷贝)就是拷贝节点的random
            cur.next.random = random == null? null : random.next;
            //cur.next.next是原链表中cur的下一个节点
            cur = cur.next.next;
        }
        //分离原链表和拷贝链表
        //1->11->2->22->3->33 分离为1->2->3和11->22->33
        cur = head;
        ListNodeWithRandom newHead = null;
        while(cur != null) {
            //取到cur的拷贝节点
            ListNodeWithRandom curCopy = cur.next;
            //如果当前节点是头节点,则它的拷贝就是新链表的头
            if(newHead == null) {
                newHead = curCopy;
            }
            //cur的下一个节点就是curCopy的下一个节点
            cur.next = curCopy.next;
            //curCopy的next取决于cur.next是否为空,如果为空,则它的next也应该为空
            //如果不为空,根据规律我们应该取cur.next的下一个节点(cur.next的拷贝)
            curCopy.next = cur.next == null? null : cur.next.next;
            //这个时候cur.next已经是cur的原链表的下一个节点了
            cur = cur.next;
        }
        return newHead;
    }

    public static void main(String[] args) {
        ListNodeWithRandom n1 = new ListNodeWithRandom(1, "1");
        ListNodeWithRandom n2 = new ListNodeWithRandom(2,"2");
        ListNodeWithRandom n3 = new ListNodeWithRandom(3, "3");
        n1.next = n2;
        n2.next = n3;
        n1.random = n3;
        n2.random = n1;
        n3.random = n2;
        ListNodeWithRandom newHead = copyLinkedList(n1);
        while(newHead != null) {
            if(newHead.next != null) {
                System.out.print(newHead + " ->");
            } else {
                System.out.print(newHead);
            }
            newHead = newHead.next;

        }
    }
}

运行结果:

{val=1, random=3', name='1''} ->{val=2, random=1', name='2''} ->{val=3, random=2', name='3''}

粗略代码,难免出错,欢迎批评指正

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

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

相关文章

计算机电脑中了勒索病毒怎么办,Windows系统中了faust勒索病毒解密数据恢复

电脑的操作系统被恶意软件攻击已不再是新鲜的话题了。而攻击的恶意软件中有一种叫做faust勒索病毒,常常袭击Windows电脑系统。如果我们的电脑在使用Windows操作系统时感染了faust勒索软件,请不要慌张,我们可以咨询专业的数据恢复厂商&#xf…

深度学习技巧应用11-模型训练中稀疏化参数与稀疏损失函数的应用

大家好,我是微学AI,今天给大家介绍一下深度学习技巧应用11-模型训练中稀疏化参数与稀疏损失函数的应用,在训练神经网络的过程中,将稀疏损失加入到常规损失函数的作用主要是降低模型复杂性和提高模型泛化能力。通过引入稀疏性约束,优化算法会在减小常规损失的同时,尽量让参…

快速上手非关系型数据库Redis

一、Redis介绍 1.非关系型数据库,纯内存操作,key-value存储,性能很高,可持久化(内存---->保存到硬盘上) 2.缓存,计数器,验证码,geo地理位置信息,发布订阅…

【前端知识】Cookie, Session,Token和JWT的发展及区别(上)

【前端知识】Cookie, Session,Token和JWT的发展及区别(上) 1. 背景2. Cookie2.1 Cookie的定义2.2 Cookie的特点2.3 Cookie的一些重要属性✨2.3.1 Cookie的重要属性🎇2.3.2 Cookie的有效期,max-age和作用域,…

SQL注入(一)联合查询 报错注入

目录 1.sql注入漏洞是什么 2.联合查询: 2.1注入思想 2.2 了解information_schema 数据库及表 3.可替代information_schema的表 3.1 sys库中重要的表 4. 无列名注入 利用 join-using 注列名。 4. 报错注入 4.1 常用函数:updatexml、extractvalue…

Java 基础进阶篇(五)—— 接口详解

文章目录 一、接口概述二、接口的基本使用三、接口从 JDK 8 开始新增的方法四、接口的注意事项(了解)补充:接口与接口的关系 一、接口概述 规范的基本特征是约束和公开。 接口就是一种规范,其约束别人必须干什么事情。 所以&…

FileZilla读取目录列表失败(vsftpd被动模式passive mode部署不正确)

文章目录 现象问题原因解决方法临时解决(将默认连接方式改成主动模式)从根本解决(正确部署vsftpd的被动模式) 现象 用FileZilla快速连接vsftpd服务器时,提示读取目录列表失败 问题原因 是我vsftpd服务端的被动模式没…

Python每日一练(20230501)

目录 1. 对链表进行插入排序 🌟🌟 2. 平衡二叉树 🌟🌟 3. 找出素数对 ※ 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 对链表进行…

Linux主机信息搜集

1、系统架构 打印系统信息 uname -a 文件 /etc/issue是一个文本文件,其中包含要在登录提示之前打印的消息或系统标识 cat /etc/issue /etc/lsb-release,/etc/redhat-release文件包含一个被解析以获取信息的描述行 cat /etc/*-release /proc/versi…

创作纪念日让 AI 与我共同记录下今天 — 【第五周年、1460天】

今天正是五一,收到一条消息? 五一还要我加班 😏? 喔,原来是 CSDN 给我发的消息呀!我在 CSDN 不知不觉已经开启第五周年啦! 目录 1.机缘2.收获3.日常4.我与 AI 的“合作”part Ipart II Super al…

java 多用户即时通信系统的实现 万字详解

目录 前言 一、拾枝杂谈 1.项目开发大体流程 : 2.多用户即时通信系统分析 : 1 需求分析 2 整体分析 二、用户登录 1.准备工作 : 2.客户端 : 1 菜单界面 2 登录验证 3 线程创建 4 线程管理 3.服务端 : 1 用户验证 2 线程创建 3 线程管理 4.登录测试 : 三、在线列表 1.…

探索深度学习世界:掌握PyTorch,成为AI领域的行家

探索深度学习世界:掌握PyTorch,成为AI领域的行家 PyTorch的背景介绍PyTorch的基本概念与特点PyTorch的基本应用张量和自动求导神经网络搭建训练和测试模型 模型的保存和加载模型保存:模型加载:模型使用: PyTorch与其他…

【KVM虚拟化】· 命令行KVM安装linux

目录 🍁基础本环境配置 🍁添加lvm卷 🍁qemu-img创建磁盘文件 🍂创建raw格式 🍂创建虚拟机 🍂转换格式为qcow2 🍁virt-install命令参数 🍁案例操作 🦐博客主页&#xff1a…

【C++】 小项目---宠物小屋的分析设计与开发实现

目录 需求 分析设计 动物类 笼子类 房子类 人类 小贴士 整体设计图 开发实现 动物类 笼子类 房子类 人类 小贴士 控制台主函数 需求 动物猫(CCat)、狗(CDog)、蛇(CSnake),包含名字&…

对折纸张厚度超过珠峰

对折 0.1 毫米的纸张,循环对折,超过珠峰高度输出对折次数。 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那么简单…… 地址&a…

【计算机网络】学习笔记:第六章 应用层【王道考研】

基于本人观看学习b站王道计算机网络课程所做的笔记&#xff0c;不作任何获利 仅进行交流分享 特此鸣谢王道考研 若有侵权请联系&#xff0c;立删 如果本篇笔记帮助到了你&#xff0c;还请点赞 关注 支持一下 ♡>&#x16966;<)!! 主页专栏有更多&#xff0c;如有疑问欢迎…

每天一道算法练习题--Day17 第一章 --算法专题 --- ----------布隆过滤器

场景 假设你现在要处理这样一个问题&#xff0c;你有一个网站并且拥有很多访客&#xff0c;每当有用户访问时&#xff0c;你想知道这个 ip 是不是第一次访问你的网站。 hashtable 可以么 一个显而易见的答案是将所有的 IP 用 hashtable 存起来&#xff0c;每次访问都去 hash…

ARM架构基本理论(1)

ARM架构基本理论 一、ARM的简介 ARM&#xff08;Advanced RISC Machine&#xff09;是一种基于RISC&#xff08;Reduced Instruction Set Computing&#xff09;架构的计算机处理器架构&#xff0c;由ARM Holdings&#xff08;ARM公司&#xff09;开发和授权给其他公司生产和…

【C++开发】基于QT+sqlite3的医疗管理系统

文章目录 前言数据库设计主要实现的功能病人列表页面病人信息页信息录入页面信息修改页面 & 信息查看页面 总结 前言 本次做的这个项目是医疗管理系统&#xff0c;是根据需求所定制的&#xff0c;因此只面向个人本地的使用。 本项目是本人在完全0基础的情况下边学边…

14-2-进程间通信-FIFO

一、命名管道FIFO 1.作用范围 对于命名管道FIFO&#xff0c;它可以在不相关的进程间也能相互通信。 2.命名管道可左右用于不相关进程的原因 因为命令管道&#xff0c;提前创建了一个类型为管道的设备文件&#xff0c;在进程里只要使用这个设备文件&#xff0c;就可以相互通信…