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

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

相关文章

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq

Redis 的 SUBSCRIBE命令详解

《Redis的SUBSCRIBE命令详解》Redis的SUBSCRIBE命令用于订阅一个或多个频道,以便接收发送到这些频道的消息,本文给大家介绍Redis的SUBSCRIBE命令,感兴趣的朋友跟随... 目录基本语法工作原理示例消息格式相关命令python 示例Redis 的 SUBSCRIBE 命令用于订

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

Vue3绑定props默认值问题

《Vue3绑定props默认值问题》使用Vue3的defineProps配合TypeScript的interface定义props类型,并通过withDefaults设置默认值,使组件能安全访问传入的... 目录前言步骤步骤1:使用 defineProps 定义 Props步骤2:设置默认值总结前言使用T

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有

MySQL8 密码强度评估与配置详解

《MySQL8密码强度评估与配置详解》MySQL8默认启用密码强度插件,实施MEDIUM策略(长度8、含数字/字母/特殊字符),支持动态调整与配置文件设置,推荐使用STRONG策略并定期更新密码以提... 目录一、mysql 8 密码强度评估机制1.核心插件:validate_password2.密码策略级