数据结构——图解链表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.mzph.cn/news/188340.shtml

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

相关文章

生成对抗网络(GAN)手写数字生成

文章目录 一、前言二、前期工作1. 设置GPU&#xff08;如果使用的是CPU可以忽略这步&#xff09; 二、什么是生成对抗网络1. 简单介绍2. 应用领域 三、网络结构四、构建生成器五、构建鉴别器六、训练模型1. 保存样例图片2. 训练模型 七、生成动图 一、前言 我的环境&#xff1…

基于SSM实现的图书管理系统

一、系统架构 前端&#xff1a;jsp | js | css | jquery | layui 后端&#xff1a;spring | springmvc | mybatis 环境&#xff1a;jdk1.7 | mysql | maven | tomcat 二、代码及数据库 三、功能介绍 01. 登录页 02. 首页 03. 借阅管理 04. 图书管理 05. 读者管理 06. 类型管理…

浏览器安全攻击与防御

前言 浏览器是我们访问互联网的主要工具&#xff0c;也是我们接触信息的主要渠道。但是&#xff0c;浏览器也可能成为攻击者利用的突破口&#xff0c;通过各种手段&#xff0c;窃取或篡改我们的数据&#xff0c;甚至控制我们的设备.本文将向大家介绍一些常见的浏览器安全的攻击…

UniTask异步解决方案

是一个高性能&#xff0c;0GC的async/await异步方案 协程缺点&#xff1a; 依赖monobehaviour 不能进行异常处理 方法返回值获取困难 c#原生Task&#xff1a; 优点&#xff1a; 不依赖monobehaviour 可以处理异常 缺点&#xff1a; Task消耗大&#xff0c;设计跨线程操作 uniTa…

【EI会议征稿】第三届网络安全、人工智能与数字经济国际学术会议(CSAIDE 2024)

第三届网络安全、人工智能与数字经济国际学术会议&#xff08;CSAIDE 2024&#xff09; 2024 3rd International Conference on Cyber Security, Artificial Intelligence and Digital Economy 第三届网络安全、人工智能与数字经济国际学术会议&#xff08;CSAIDE 2024&#…

c题目13:验证100以内的数是否满足哥德巴赫猜想。(任一大于2的偶数都可以写成两个质数之和)

每日小语 活下去的诀窍是&#xff1a;保持愚蠢&#xff0c;又不能知道自己有多蠢。——王小波 自己思考 即要让第一个质数与这个数减去第一个质数的值都为质数&#xff0c;所以要满足几个条件 1.abc 2.a为质数 3.b为质数 这里是否可以用到我之前刚学的自己设置的那个判断…

带头结点的双向循环链表

目录 带头结点的双向循环链表 1.存储定义 2.结点的创建 3.结点的初始化 4.尾插结点 5.尾删结点 6.头插结点 7.头删结点 8.查找并返回结点 9.在pos结点前插入结点 10.删除pos结点 11.打印链表 12.销毁链表 13.头插结点2.0版 14.尾插结点2.0版 前言&#xff1a; 当…

深入探究Python中的JSON、Pickle和Shelve模块:特性与区别

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 在Python中&#xff0c;处理数据序列化和持久化是极其重要的。JSON、Pickle和Shelve是三种常用的模块&#xff0c;它们提供了不同的方法来处理数据的序列化和持久化。本文将深入研究这三个模块&#xff0c;探讨它…

conda和pip常用命令整理

文章目录 一、conda常用指令1. 更新2 .环境管理3. 包管理 二、pip常用命令1. 常用命令2. 国内镜像 一、conda常用指令 1. 更新 conda --version 或 conda -V #查看conda版本 conda update conda # 基本升级 conda update anaconda # 大的升级 conda upd…

VBA_MF系列技术资料1-232

MF系列VBA技术资料 为了让广大学员在VBA编程中有切实可行的思路及有效的提高自己的编程技巧&#xff0c;我参考大量的资料&#xff0c;并结合自己的经验总结了这份MF系列VBA技术综合资料&#xff0c;而且开放源码&#xff08;MF04除外&#xff09;&#xff0c;其中MF01-04属于定…

动态规划:多重背包问题-一维滚动数组解法

题目描述 你是一名宇航员&#xff0c;即将前往一个遥远的行星。在这个行星上&#xff0c;有许多不同类型的矿石资源&#xff0c;每种矿石都有不同的重要性和价值。你需要选择哪些矿石带回地球&#xff0c;但你的宇航舱有一定的容量限制。 给定一个宇航舱&#xff0c;最大容量…

02_学习使用javax_ws_rs_下载文件

文章目录 1 前言2 Maven 依赖3 下载接口4 如何返回文件&#xff1f;5 感谢 1 前言 专栏上一篇&#xff0c;写了如何使用 javax.ws.rs 上传文件&#xff0c;那么必然的&#xff0c;我们得再学习学习如何下载文件&#x1f600; 2 Maven 依赖 这个就不赘述了&#xff0c;和上一篇…

【高效开发工具系列】Hutool DateUtil工具类

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

网络爬虫与指纹浏览器:解析指纹浏览器对网络爬虫的作用

网络爬虫在信息搜集、数据挖掘等领域起着重要作用。然而&#xff0c;传统爬虫往往面临被目标网站封禁的风险。本文将介绍指纹浏览器对网络爬虫的作用&#xff0c;以及指纹浏览器如何帮助爬虫降低封禁风险。 网络爬虫面临的挑战 网络爬虫是一种自动化程序&#xff0c;用于从互联…

Python+Requests模块获取响应内容

Requests模块获取响应内容 响应包括响应行、响应头、响应正文内容&#xff0c;这些返回的响应信息都可以通过Requests模块获取。这些 获取到的响应内容也是接口测试执行得到的实际结果。 获取响应行 获取响应头 获取其它响应信息 代码示例&#xff1a; # 导入requests模块…

华为OD机试真题-分割均衡字符串-2023年OD统一考试(C卷)

题目描述&#xff1a; 均衡串定义&#xff1a;字符串只包含两种字符&#xff0c;且两种字符的个数相同。 给定一个均衡字符串&#xff0c;请给出可分割成新的均衡子串的最大个数。 约定字符串中只包含大写的X和Y两种字符。 输入描述&#xff1a; 均衡串&#xff1a;XXYYXY 字符…

算法通关村第十四关-青铜挑战认识堆

大家好我是苏麟 , 今天带大家认识认识堆 . 堆 堆是将一组数据按照完全二叉树的存储顺序&#xff0c;将数据存储在一个一维数组中的结构。 堆有两种结构&#xff0c;一种称为大顶堆&#xff0c;一种称为小顶堆 : 大顶堆 大顶堆的任何一个父节点的值&#xff0c;都大于或等于…

前端下拉框select标签的插件——select2.js

本文采用的是select2 版本:Select2 4.0.6-rc.1。 可以兼容IE8及以上。亲测过。 官网:Getting Started | Select2 - The jQuery replacement for select boxes 一、认识select2.js 1、使用插件,首先要引入别人的插件了,你可以选择离线(无网络)或者在线引用的(如果有网…

ios 逆向分分析,某业帮逆向算法(一)

用到工具: 爱思助手CrackerXL(砸壳软件)越狱手机ida反汇编软件分析login 的sign 签名算法中自己写算法 已知我们32位,我们不妨猜测是md5 ,那我们试图使用CC_MD5 ,这个是ios 中的标准库, 我们使用frida-trace 注入hook一下,看看有没有 经过 是经过了这个函数,密码也是…

新建的springboot项目中application.xml没有绿色小叶子(不可用)

经常有朋友会遇到新建了一个springboot项目&#xff0c;发现为啥我创建的application.xml配置文件不是绿色的&#xff1f;&#xff1f;&#xff1f; 下面教大家如何解决&#xff0c;这也是博主在做测试的时候遇到的&#xff1a; 将当前位置application.xml删掉&#xff0c;重新…