数据结构——图解链表OJ题目

        学完了单链表之后,我们对其基本结构已经有了一定的了解,接下来我们通过一些题目强化对链表的理解,同时学习一些面试笔试题目的新思路以及加强对数据结构单链表的掌握。 


目录

题目一.876. 链表的中间结点 - 力扣(LeetCode)

题目二:21. 合并两个有序链表 - 力扣(LeetCode)

题目三:203. 移除链表元素 - 力扣(LeetCode)

题目四: 206. 反转链表 - 力扣(LeetCode)

题目五:141. 环形链表 - 力扣(LeetCode)

题目六: 142. 环形链表 II - 力扣(LeetCode)


题目一.876. 链表的中间结点 - 力扣(LeetCode)

  • 给你单链表的头结点 head ,请你找出并返回链表的中间结点。
  • 如果有两个中间结点,则返回第二个中间结点。

我们一起来思考一下这道题目:返回链表的中间结点。我们先来了解一种新思路:快慢指针!我们定义两个指针:一个快指针,一个慢指针。每次快指针走两步,慢指针走一步。我们来看一下演示过程:

一个中间结点情况:

两个中间结点情况:

通过演示过程我们可以清楚的看到:

  • 如果是奇数结点,当fast指向尾结点,slow返回中间结点。
  • 如果是偶数结点,当fast指向空时(越过尾结点),slow返回中间结点。

总结以上规律,应在当 fast遇到或越过尾节点时跳出循环,并返回 slow 即可。

struct ListNode* middleNode(struct ListNode* head) {struct ListNode* slow=head,*fast=head;while(fast&&fast->next){slow=slow->next;fast=fast->next->next;}return slow;
}

题目二:21. 合并两个有序链表 - 力扣(LeetCode)

  • 将两个升序链表合并为一个新的 升序 链表并返回。
  • 新链表是通过拼接给定的两个链表的所有节点组成的。

我们要返回一个升序的新链表,那么我们可以借助一个头指针,将list1和list2进行比较,值小的尾插放入新的链表中,再用头指针指向新的链表就可以。

在题目中注意判断list1为空,list2为空是怎么办?

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {struct ListNode*head=NULL,*tail=NULL;// 处理特殊情况if(list1==NULL)return list2;if(list2==NULL)return  list1;while(list1&&list2){if(list1->val<list2->val){if(tail==NULL)tail=head=list1;else{tail->next=list1;tail=tail->next;}list1=list1->next;}else{if(tail==NULL)tail=head=list2;else{tail->next=list2;tail=tail->next;}list2=list2->next;}}if(list1)tail->next=list1;if(list2)tail->next=list2;return head;
}

题目三:203. 移除链表元素 - 力扣(LeetCode)

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

思路一:我们定义一个指针,让这个指针移动从而去寻找链表中和val相等的值,要是遇到就把它释放掉,然后把上一个结点和释放掉后的下一个结点连接起来,最后返回头结点head就可以。但这个思路有什么问题我们想一想?如果头结点就需要释放呢,那我们就要把返回的头结点此时后移,注意考虑这个情况!

大家可以自己思考一下,再参考下面代码。

struct ListNode* removeElements(struct ListNode* head, int val) {struct ListNode*prev=NULL,*cur=head;while(cur){if(cur->val==val){if(cur==head){head=cur->next;free(cur);cur=head;//cur=head->next错误}else{prev->next=cur->next;free(cur);cur=prev->next;}}else{prev=cur;cur=cur->next;}}return head;
}

思路二:我们定义一个新的结点,当指针指向的值不等于val值的时候,把结点连接到新结点上。这样返回的新的头结点就是一个没有val值的链表。

大家可以自己思考一下,再参考下面代码。

struct ListNode* removeElements(struct ListNode* head, int val) {struct ListNode* cur=head;struct ListNode* tail=NULL,*newnode=NULL;while(cur){if(cur->val==val){struct ListNode* node=cur;cur=cur->next;free(node);}else{if(tail==NULL){newnode=tail=cur;}else{tail->next=cur;tail=tail->next;}cur=cur->next;}}if(tail)tail->next=NULL;return newnode;
}

题目四: 206. 反转链表 - 力扣(LeetCode)

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

还记得之前写的线性表头插吗?我们发现头插和输入的顺序刚好相反,那我们把这个思想用在这道题目上,我们把链表的值头插到新的一个链表中,返回头插后的链表的头结点。

struct ListNode* reverseList(struct ListNode* head) {struct ListNode* cur=head;struct ListNode* newhead=NULL;while(cur){struct ListNode* next=cur->next;cur->next=newhead;newhead=cur;cur=next;}return newhead;
}

题目五:141. 环形链表 - 力扣(LeetCode)

  • 给你一个链表的头节点 head ,判断链表中是否有环。
  • 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
  • 如果链表中存在环 ,则返回 true 。 否则,返回 false 。

这个题目超级有意思,检查链表里有没有环,还记得我们的快慢指针吗?如果有环的话,快指针肯定先入环,慢指针如果在环中和快指针相遇了,说明有环;如果没有相遇,说明无环。

大家肯定有一个问题:为什么有环就一定可以追上,我们一起分析一下。当slow进环后,fast开始追击,假设它们之间的距离为N,那么走一次,它们之间的距离变为N-1,下一次为N-2,N-3,......3,2,1,0,最后它们之间的距离就是0。所以只要有环,它们一定会相遇。

bool hasCycle(struct ListNode *head) {struct ListNode* slow=head,*fast=head;while(fast&&fast->next)//快指针将到达链表尾部,该链表不为环形链表{slow=slow->next;fast=fast->next->next;if(slow==fast)return true;}return false;
}

题目六: 142. 环形链表 II - 力扣(LeetCode)

  • 给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
  • 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

这个题目其实有点数学题的意思,我们来分析一下:假设起点到入口点的距离是L,环的周长是C,入口点到相遇点距离是X,我们已经分析过,slow进环后一圈内,fast必追上slow,那么slow的距离就是:L+X,fast的距离是L+n*C+X,L可能很长,导致fast已经在环里走路不止一圈,slow才进入,所以fast是n*C,那么我们已知fast走的距离是slow的两倍,这是快慢指针的定义,所以我们列出式子:2(L+X)=L+n*C+X,解出L=(n-1)*C+C-X.也就是说,一个指针从起点走,另一个从相遇点走,他们会在入口点相遇。

struct ListNode *detectCycle(struct ListNode *head) {struct ListNode* slow,*fast;slow=fast=head;while(fast&&fast->next){slow=slow->next;fast=fast->next->next;if(slow==fast){struct ListNode* meet=slow;while(head!=meet){meet=meet->next;head=head->next;}return meet;}}return NULL;
}

今天的分享就到这里,大家有哪里不懂的可以私信我,或在评论区讨论,大家可以把这些题目作为链表的练习题目,希望对大家的编程和数据结构有帮助! 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

14.Tomcat和HTTP协议-[一篇通]

文章目录 1.HTTP 协议1.1HTTP 是什么1.2理解 "应用层协议"1.3理解 HTTP 协议的工作过程1.4HTTP 协议格式1.4.1抓包工具的使用(Fiddler)1.4.2抓包工具的原理1.4.3抓包结果1.4.4协议格式总结 1.5HTTP 请求 (Request)1.5.1认识 URL1.5.1.1URL 基本格式1.5.1.2关于 URL e…

二次元检测设备导轨修复指南

二次元检测设备是一种高精度的测量仪器&#xff0c;用于检测物体表面的形状、尺寸和精度等。直线导轨是二次元检测设备中最重要的组成部分之一&#xff0c;它的精度和稳定性直接影响到设备的测量结果和可靠性&#xff0c;因此&#xff0c;对导轨进行修复和保养是非常重要的。 直…

网站实现验证码功能

一、验证码 一般来说&#xff0c;网站在登录的时候会生成一个验证码来验证是否是人类还是爬虫&#xff0c;还有一个好处是防止恶意人士对密码进行爆破。 二、流程图 三、详细说明 3.1 后端生成验证码 Override public Result<Map<String, String>> getVerifica…

Linux安装nginx超完整步骤

1、到官网&#xff08;http://nginx.org&#xff09;下载nginx包,推荐使用稳定版本 2、上传nginx到linux系统&#xff0c;我上传的默认路径在/usr/local/下 3、安装依赖环境&#xff1a; ①安装gcc环境 yum install gcc-c ②安装PCRE库&#xff0c;用于解析正则表达式 yum…

MinkowskiEngine安装

pip install torch ninjagit clone https://github.com/NVIDIA/MinkowskiEngine.git cd MinkowskiEngine安装之前先把并行安装的thread数降低&#xff0c;否则会导致进程卡死。 打开setup.py文件内位于142行的MAX_COMPILATION_THREADS变量值从12改成4。 export CXXg-7 python…

深入理解Zookeeper系列-1.初识Zoookeeper

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理&#x1f525;如果感觉博主的文章还不错的话&#xff…

办公软件PDF转换工具 - Bruce的PDF工具pdftool

Bruce的PDF工具 - 办公软件PDF转换工具 - pdftool&#xff0c;支持&#xff1a; 1、图片转PDF&#xff0c;支持图片自动压缩&#xff0c;可预览图片 2、合并PDF&#xff0c;支持多个PDF合并成一个PDF 3、PDF转图片&#xff0c;PDF的每页转成一张图片 4、OFD转PDF&#xff0c;O…

操作系统进程与线程篇

目录 一、进程 1.1、进程状态 1.2、进程的控制结构 1.3、进程的控制 1.4、进程的上下文切换 二、线程 2.1.线程是什么 2.2、线程与进程的比较 2.3、线程的上下文切换 2.4、线程的实现 2.5、轻量级线程 三、进程间的通信方式 3.1、管道 3.2、消息队列 3.3、共享内…

手摸手Element-ui路由VueRoute

后端WebAPI准备 https://router.vuejs.org/zh/guide/ https://v3.router.vuejs.org/zh/installation.html 路由 <template> <el-table :data"tableData" style"width: 100%" :row-class-name"tableRowClassName"…

国产linux单用户模式破解无密码登陆 (麒麟系统用户登录密码遗忘解决办法)

笔者手里有一批国产linu系统&#xff0c;目前开始用在日常的工作生产环境中&#xff0c;我这个老程序猿勉为其难的充当运维的或网管的角色。 国产linux系统常见的为麒麟Linux&#xff0c;统信UOS等&#xff0c;基本都是基于debian再开发的linux。 问题描述&#xff1a; 因为…

Neo4j 数据库管理 数据备份与恢复(头歌)

文章目录 第1关&#xff1a;数据备份与恢复任务描述相关知识数据备份数据导入 编程要求测试说明答案测试前准备Cypher 代码数据备份与导入 第1关&#xff1a;数据备份与恢复 任务描述 本关任务&#xff1a;熟练掌握数据备份与恢复。 相关知识 为了完成本关任务&#xff0c;…

Python全栈之基本数据类型详解

文章目录 1.注释2.输出3.变量4.命名规范5.变量的定义方式1.字符串类型2.数字类型3.List列表类型4.tuple 元组类型的定义5.Dict字典类型6.set集合类型7.数据类型转换8.自动类型转换9.强制类型转换关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品…

ZeroTier外网访问实验室Linux服务器

ZeroTier外网访问实验室Linux服务器 1、在ZeroTier上创建一个自己的Network 进入ZeroTier的官网https://www.zerotier.com/注册一个账号 注册完之后登录进去&#xff0c;创建自己的Network 创建完之后来到IPv4的分配管理&#xff0c;选择主机位只有后8位的IP&#xff0c;才能…

SAP 如何检查已安装的SAP UI5 版本

第一个方法是直接从FLP中查看 但是部分高版本的FLP中没有这个about&#xff0c; 那么在当前界面可以使用&#xff1a;CTRL ALT SHIFT S 查看当前版本 根据此版本&#xff0c;去进行你的UI5的开发吧

全志XR806基于FreeRTOS下部署竞技机器人先进模糊控制器

前言 很荣幸参与到由“极术社区和全志在线联合组织”举办的XR806开发板试用活动。本人热衷于各种的开发板的开发&#xff0c;同时更愿意将其实现到具体项目中。秉承以上原则&#xff0c;发现大家的重心都放在开发中的环境构建过程&#xff0c;缺少了不少实际应用场景的运用&am…

算法:笛卡尔平面坐标系上,若干连接点形成线,剔除距离小于阈值的点,Kotlin

算法&#xff1a;笛卡尔平面坐标系上&#xff0c;若干连接点形成线&#xff0c;剔除距离小于阈值的点&#xff0c;Kotlin const val THRESHOLD 0.6f //距离小于这个点将被剔除。data class Point(val x: Float, val y: Float)fun removeNearbyPoint(points: List<Point>…

人工智能对我们的生活影响

文章目录 一、人工智能主要领域二、人工智能的应用三、对人工智能的看法 一、人工智能主要领域 人工智能&#xff08;AI&#xff09;涵盖了多个领域&#xff0c;其应用广泛&#xff0c;正在不断拓展。以下是人工智能的一些主要领域&#xff1a; &#xff08;1&#xff09;机器…

《ChatGPT实操应用大全》探索无限可能

&#x1f5e3;️探索ChatGPT&#xff0c;开启无限可能&#x1f680; 文末有免费送书福利&#xff01;&#xff01;&#xff01; ChatGPT是人类有史以来最伟大的发明。他能写作、绘画、翻译、看病、做菜、编程、数据分析、制作视频、解高等数学题…&#xff0c;他会的技能…

mysql从库设置为只读

直奔主题&#xff0c;mysql设置为只读后&#xff0c;无法增删改。 设置命令&#xff1a; mysql> set global read_only1; #1是只读&#xff0c;0是读写 mysql> show global variables like %read_only%; 以下是相关说明&#xff1a; 1、对于数据库读写状态&#xf…

数据库-MySQL之数据库必知必会17-21章

第17章 组 合 查 询 创建组合查询 可用UNION操作符来组合数条SQL查询。利用UNION&#xff0c;可给出多条SELECT语句&#xff0c;将它们的结果组合成单个结果集。 **例子&#xff1a;**假如需要价格小于等于5的所有物品的一个列表&#xff0c;而且还想包括供应商1001和1002生产…