数据结构单链表”质检员“*2

news/2024/5/17 7:33:04

1.随机链表的逻辑结构复制

原题链接:

. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode-cn.com/problems/copy-list-with-random-pointer/description/        据说做这道题,能把思路想明白,并且能把思路转化为代码,那说明单链表掌握水平就有八成的功力了。

        这道题如果只是复制一份链表,那还是简单的,麻烦的地方在于,让新链表结点成员“random”与原来的链表逻辑地址相符。此处会有三个坑:

        坑1:如果原封不动的把random抄过来,会变成下面这副模样,新节点的random指着原来的链表。

        坑2:如果根据结点的val值来确定random指向的是谁,会出现下面的情况,遇到相同val值出错:

        坑3:如果先记下每个节点的random指向的是第几个节点,之后再根据记下的位置给复制的结点的random赋值,这样做虽然可以,但是时间复杂度过高:N(n^2),得遍历每一个结点并通过遍历找到每个结点指向的结点是第几个。

        问题的关键在于,我们需要一个东西来帮我们记住指向的结点是第几个,依靠暴力统计是不合理的,唯一剩下的能表达位置关系的只有原链表本身,那我们我们该怎么利用呢?

        让新链表长在旧链表上:

        如图所示,在原链表每个结点后面插入复制的新结点,这样做的好处是,我们可以方便的确定新结点的random:原理如下

        思路解决了,总的代码如下:
 

// 创建新节点
struct Node* createNode(int val) {struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));if (newNode == NULL) {printf("Memory allocation failed\n");exit(0);}newNode->val = val;newNode->next = NULL;newNode->random = NULL;return newNode;
}// 拷贝链表函数
struct Node* copyRandomList(struct Node* head) {if (head == NULL) return NULL;// 第一步:在每个原节点旁边创建新节点,新节点的next指向下一个原节点struct Node* current = head;while (current != NULL) {struct Node* newNode = createNode(current->val);newNode->next = current->next;current->next = newNode;current = newNode->next;}// 第二步:根据原节点的random指针设置新节点的random指针current = head;while (current != NULL) {if (current->random != NULL) {current->next->random = current->random->next;}current = current->next->next;}// 第三步:拆分链表struct Node* newHead = head->next;struct Node* newCurrent = newHead;current = head;while (current != NULL) {current->next = newCurrent->next;if (current->next != NULL) {newCurrent->next = current->next->next;}current = current->next;newCurrent = newCurrent->next;}return newHead;
}

        这里解释一下为什么不在创建结点的阶段就把random确定好:原因1是没有创建后面的结点是不能知道应该指向哪里的,原因2是哪怕只是为了取巧通过考试测试用例,也会有错误:

        假设原来的第三个结点指向了第五个结点,如果边创建新结点边给random赋值,按照之前的思路,他指向的random的情况会是这样的:

        他指向了不该指向的NULL;

2.带环链表找入口

原题链接:

. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode-cn.com/problems/linked-list-cycle-ii/description/首先我们需要判断链表是否带环:
        建立一个快指针(一次走俩个结点)和一个慢指针(一次走一个结点),俩者从起点出发,如果中途相遇,则说明带环,若快指针next到了NULL,说明不带环。

        由于快慢指针的相对速度是1(没走一次距离变化为1),所以不会出现错过的情况。

        道理比较简单,实现方式如下:
 

bool hasCycle(struct ListNode *head) {struct ListNode* fast = head,*slow = head;while(fast&&fast->next){fast = fast->next->next;slow = slow->next;if(slow == fast)return true;}return false;
}

        注意fast一次走俩步,所以要判断fast和fast的下一个是不是NULL来确定是否到结尾。

        此时我们可以顺手加一个变量n来记录慢指针行动的次数:之后会用他找相遇点,修改后的代码如下:

int hasCycle(struct ListNode *head) {struct ListNode* fast = head,*slow = head;int n = 0;//n是slow走的步数while(fast&&fast->next){fast = fast->next->next;slow = slow->next;n++;if(slow == fast)return n;}return -1;//跳出循环,说明不带环,-1表示不带环
}

        我们不用担心slow与fast相遇时,slow在环里转了很多圈,推理图如下:

        我们通过前面的hasCycl函数可以得到去相遇点的步数,只需要让一个慢指针从head开始走n步就可以获取相遇点的地址了:

        此时,如果定义俩个慢指针分别指向head和相遇点,让他们一次走一个结点,最后他们会在入口相遇,这个入口的地址就是这个题目需要的答案,这里解释一下为什么这么巧:

        这道题思路解决后,代码实现是很简单的。


http://www.mrgr.cn/p/14882737

相关文章

智慧旅游引领旅游行业创新发展:借助智能科技的力量,推动旅游服务的个性化、精准化,提升游客的满意度和忠诚度

随着信息技术的迅猛发展和广泛应用,智慧旅游已成为旅游行业创新发展的重要引擎。智慧旅游借助智能科技的力量,推动旅游服务的个性化、精准化,不仅提升了游客的满意度和忠诚度,也为旅游行业的可持续发展注入了新的活力。本文将从智…

《Vid2Seq》论文笔记

原文链接 [2302.14115] Vid2Seq: Large-Scale Pretraining of a Visual Language Model for Dense Video Captioning (arxiv.org) 原文笔记 What: 《Vid2Seq: Large-Scale Pretraining of a Visual Language Model for Dense Video Captioning》 作者提出一种多…

《软件设计师教程:数据库系统基础知识大总结》

​ 个人主页:李仙桎 🔥 个人专栏: 《软件设计师》 ⛺️生活的理想,就是为了理想的生活! ​ ⛺️前言:各位铁汁们好啊!!!今天继续正式学习中级软件设计师考试相关的内容,后续不断更新…

Ansible 自动化运维

一、介绍 1、定义: ansible是自动化运维工具,基于Python开发,具有批量系统配置、批量程序部署、批量运行命令等功能。 ansible是基于 paramiko(框架) 开发的,并且基于模块化工作,本身没有批量…

node.js egg.js

Egg 是 Node.js 社区广泛使用的框架,简洁且扩展性强,按照固定约定进行开发,低协作成本。 在Egg.js框架中,ctx 是一个非常核心且常用的对象,全称为 Context,它代表了当前 HTTP 请求的上下文。ctx 对象封装了…

java中serverlet的体系结构

GenericServlet继承三个接口,HttpServerlet继承GenericServlet

React-editor-js not showing up in a function component

React-editor-js not showing up in a function component react-editor-js 在react 函数组件中显示不出来 真的,我马上就想放弃它了。但是看它周下载量还挺多,我不信别人没遇到过。于是我继续在网络上挖呀挖。只是我一开始的方向错了。我一直以为我的写…

Profinet转Modbus网关接称重设备与1200PLC通讯

Profinet转Modbus网关(XD-MDPN100)是一种能够实现Modbus协议和Profinet协议之间转换的设备。Profinet转Modbus网关可提供单个或多个RS485接口,使用Profinet转Modbus网关将称重设备与西门子1200 PLC进行通讯,可以避免繁琐的编程和配置过程,节省了工程师的时间和精力。其次,…

自动驾驶横向控制算法

本文内容来源是B站——忠厚老实的老王,侵删。 三个坐标系和一些有关的物理量 使用 frenet坐标系可以实现将车辆纵向控制和横向控制解耦,将其分开控制。使用右手系来进行学习。 一些有关物理量的基本概念: 运动学方程 建立微分方程 主要是弄…

给Qt搭建一个简单的Json服务器用于软件调试

一. vscode+nodejs+npm安装 二. nodejs服务器开启打开vscode - 终端 - 新建终端进入json_server目录 cd D:\json_server运行启动命令, 启动json-server服务器 npm run json:server效果如下: PS D:\json_server> npm run json:server> jsonserver@1.0.0 json:server > …

酒店订单管理系统搭建教程

1、演示环境配置 centos7.9、mysql5.7、php7.2 2、宝塔创建站点记录创建站点时候创建的数据库信息3、上传fastadmin压缩包点击开始上传 4、解压上传的fastadmin5、配置网站目录和运行目录运行目录选择public点击保存即可 6、配置伪静态选择thinkphp 7、直接访问域名根据自己的实…

加速软件定义汽车进程:安波福推出全栈式软硬件平台

随着智能汽车行业的飞速发展,“软件定义汽车”也得到了越来越多行业人士的认可,成为了汽车行业的大势所趋。为了推动和加速软件定义汽车的进程,也有越来越多的科技企业在为其不断添砖加瓦。 2024北京国际车展期间,安波福正式对外展…

14、pWnOS_v2.0(VulnHub)

pWnOS_v2.0 一、nmap 靶机ip找不见的自行上网查找解决办法。二、web渗透 目录爆破/blog/whatweb/search.php/register.php qwe 123qwe点击给定的链接兔子洞,无法登入?一直卡在这个界面wfuzz貌似没什么用nmap -> 目录Simple PHP Blog 0.4.0perl 1191.pl如果出现运行报错Can…

SQL Server实战三:数据库表完整性约束及索引、视图的创建、编辑与删除

本文介绍基于Microsoft SQL Server软件,实现数据库表完整性约束、索引与视图的创建、编辑与删除等操作的方法~本文介绍基于Microsoft SQL Server软件,实现数据库表完整性约束、索引与视图的创建、编辑与删除等操作的方法。 目录1 交互式为数据库表S创建PRIMARY KEY约束2 交互…

上位机开发-PyQt5

PyQt是一套Python的GUI开发框架,即图形用户界面开发框架 其中PyQt是Qt(C语言实现的)为Python专门提供的扩展 PySide官网:Qt for Python 插件安装 pip install 插件名字 # 安装 pip uninstall 插件名字 # 卸载 pip install 插件名字 -i 指定下载的镜…

vue.js 3 初学经验:开发环境搭建,Windows,nginx

Windows 11 nginx-1.20.0 "vue": "^3.4.21" ---序章 vue3 开发,不需要后端服务业是可以的。 在需要后端服务时,使用 nginx 来转发请求是很好的(个人开发者)。注,还有什么其它方式吗? 注,本文的后端服务 是使用 Java 开发的 HTTP 接口。 注,参考资料…

怎么给字符串字段加索引?

怎么给字符串字段加索引? 现在,几乎所有的系统都支持邮箱登录,如何在邮箱这样的字段上建立合理的索引,是我们今天要讨论的问题。 假设,你现在维护一个支持邮箱登录的系统,用户表是这么定义的: …

使用图集Atlas创建Fnt文件的工具

fnt文件生成unity字体的原理其实就是渲染图集Atlas上的Sprite,这边直接利用Unity自带的图集工具生成fnt文件 注意:这里生成的fnt文件还没发直接用,因为没有关联字符,这个工具只是第1步,要配合Fnt编辑工具一起使用 public class SpriteToFntTool : EditorWindow {[MenuItem…

ffmpeg与sdl的个人笔记

说明 这里的ffmpeg基础知识和sdl基础知识仅提及与示例代码相关的知识点, 进阶可学习雷神的博客。 https://blog.csdn.net/leixiaohua1020 当然,如代码写的有问题或有更好的见解,欢迎指正! 音视频基础知识 在学习音视频理论知识时&#xff…