链表的相交和带环问题详解

2023-10-19 20:59

本文主要是介绍链表的相交和带环问题详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

弃我去者,昨日之日不可留; 乱我心者,今日之日多烦忧。 长风万里送秋雁,对此可以酣高楼。 蓬莱文章建安骨,中间小谢又清发。
俱怀逸兴壮思飞,欲上青天揽明月。 抽刀断水水更流,举杯消愁愁更愁。 人生在世不称意,明朝散发弄扁舟。
——李白

文章目录

    • 判断链表是否相交
    • 求两个相交链表的交点
    • 判断链表是否带环
    • 求带环链表的环入口点

请添加图片描述

判断链表是否相交

思路:如果两个链表的最后一个节点是同一个节点,那一定相交
注意:这里不是值相等就是同一个节点.
这个代码我就不敲了,比较简单,而且求交点的代码里面有

求两个相交链表的交点

//给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {//判断链表是否为空if(headA==NULL||headB==NULL){return NULL;}//判断是否相交struct ListNode* cura=headA;struct ListNode* curb=headB;
//注意,int sizea,sizeb=1;  这种写法会默认sizea是0,导致错误int sizea=1;int sizeb=1;while(cura->next){cura=cura->next;sizea++;}while(curb->next){curb=curb->next;sizeb++;}if(cura!=curb){return NULL;}//相交 长链表先走差值步struct ListNode* curA=headA;struct ListNode* curB=headB;int gap=sizea-sizeb;if(gap>0){while(gap){curA=curA->next;gap--;}}else{while(gap){curB=curB->next;gap++;}}//对齐之后一起走,直到遇到同一个节点
while(curA!=curB){curA=curA->next;curB=curB->next;}return curA;}

判断链表是否带环

方法:快慢指针
主要分析:
快指针为什么一次走两步慢指针一次走一步,如果是快指针一次走三步走四步可不可以?
不可以
因为快指针一次走两步与慢指针的步数差是1,而一个环最小的节点数是2,就不会发生每次快指针都恰好绕过一圈而导致的快慢指针不相遇的问题

在这里插入图片描述
画一个简单的图来看,如果快指针一次走三步,就会恰好每次都错过慢指针

下面是代码实现

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
bool hasCycle(struct ListNode *head) {//用快慢指针,快指针一次两步,慢指针一次一步,带环一定相遇struct ListNode* fast=head;struct ListNode* low=head;while(fast&&fast->next){fast=fast->next->next;low=low->next;if(fast==low){return true;}}return false;}

求带环链表的环入口点

在这里插入图片描述
方式一:
从相遇点的位置将环断开,就转化成求两个链表交点问题,最后不要忘记将环合上.
方式二:
(这是大佬的方法,让我们一起学习一下)
在这里插入图片描述

下图是这个方法的证明过程,比较复杂需要画图理解,有点像数学几何的思想,仔细看这个过程,不复杂只是很巧妙!
在这里插入图片描述
下面是方式二的代码实现

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
typedef struct ListNode node;
node* hascycle(node*head)
{node* fast=head;node* low=head;while(fast&&fast->next){fast=fast->next->next;low=low->next;if(fast==low){return fast;}}return NULL;
}
struct ListNode *detectCycle(struct ListNode *head) {if(head==NULL){  return NULL;}node* pm=hascycle(head);node* ph=head;if(pm==NULL){return NULL;}while(pm!=ph){pm=pm->next;ph=ph->next;}return pm;
}

链表这里有很多需要理解的地方,
可能很多人觉得链表的算法比较难,
实际上是因为对链表的理解和应用还是不够深入,多练习,多思考每一个算法,
其实几天下来就拿下链表了!!
加油!!!请添加图片描述

这篇关于链表的相交和带环问题详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/242344

相关文章

Go语言使用select监听多个channel的示例详解

《Go语言使用select监听多个channel的示例详解》本文将聚焦Go并发中的一个强力工具,select,这篇文章将通过实际案例学习如何优雅地监听多个Channel,实现多任务处理、超时控制和非阻... 目录一、前言:为什么要使用select二、实战目标三、案例代码:监听两个任务结果和超时四、运行示例五

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

解决pandas无法读取csv文件数据的问题

《解决pandas无法读取csv文件数据的问题》本文讲述作者用Pandas读取CSV文件时因参数设置不当导致数据错位,通过调整delimiter和on_bad_lines参数最终解决问题,并强调正确参... 目录一、前言二、问题复现1. 问题2. 通过 on_bad_lines=‘warn’ 跳过异常数据3

idea的终端(Terminal)cmd的命令换成linux的命令详解

《idea的终端(Terminal)cmd的命令换成linux的命令详解》本文介绍IDEA配置Git的步骤:安装Git、修改终端设置并重启IDEA,强调顺序,作为个人经验分享,希望提供参考并支持脚本之... 目录一编程、设置前二、前置条件三、android设置四、设置后总结一、php设置前二、前置条件

解决RocketMQ的幂等性问题

《解决RocketMQ的幂等性问题》重复消费因调用链路长、消息发送超时或消费者故障导致,通过生产者消息查询、Redis缓存及消费者唯一主键可以确保幂等性,避免重复处理,本文主要介绍了解决RocketM... 目录造成重复消费的原因解决方法生产者端消费者端代码实现造成重复消费的原因当系统的调用链路比较长的时

python中列表应用和扩展性实用详解

《python中列表应用和扩展性实用详解》文章介绍了Python列表的核心特性:有序数据集合,用[]定义,元素类型可不同,支持迭代、循环、切片,可执行增删改查、排序、推导式及嵌套操作,是常用的数据处理... 目录1、列表定义2、格式3、列表是可迭代对象4、列表的常见操作总结1、列表定义是处理一组有序项目的

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3