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

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

相关文章

HTML5的input标签的`type`属性值详解和代码示例

《HTML5的input标签的`type`属性值详解和代码示例》HTML5的`input`标签提供了多种`type`属性值,用于创建不同类型的输入控件,满足用户输入的多样化需求,从文本输入、密码输入、... 目录一、引言二、文本类输入类型2.1 text2.2 password2.3 textarea(严格

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

MySQL中between and的基本用法、范围查询示例详解

《MySQL中betweenand的基本用法、范围查询示例详解》BETWEENAND操作符在MySQL中用于选择在两个值之间的数据,包括边界值,它支持数值和日期类型,示例展示了如何使用BETWEEN... 目录一、between and语法二、使用示例2.1、betwphpeen and数值查询2.2、be

python中的flask_sqlalchemy的使用及示例详解

《python中的flask_sqlalchemy的使用及示例详解》文章主要介绍了在使用SQLAlchemy创建模型实例时,通过元类动态创建实例的方式,并说明了如何在实例化时执行__init__方法,... 目录@orm.reconstructorSQLAlchemy的回滚关联其他模型数据库基本操作将数据添

Java中ArrayList与顺序表示例详解

《Java中ArrayList与顺序表示例详解》顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构,:本文主要介绍Java中ArrayList与... 目录前言一、Java集合框架核心接口与分类ArrayList二、顺序表数据结构中的顺序表三、常用代码手动

JAVA线程的周期及调度机制详解

《JAVA线程的周期及调度机制详解》Java线程的生命周期包括NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED,线程调度依赖操作系统,采用抢占... 目录Java线程的生命周期线程状态转换示例代码JAVA线程调度机制优先级设置示例注意事项JAVA线程

Springboot3统一返回类设计全过程(从问题到实现)

《Springboot3统一返回类设计全过程(从问题到实现)》文章介绍了如何在SpringBoot3中设计一个统一返回类,以实现前后端接口返回格式的一致性,该类包含状态码、描述信息、业务数据和时间戳,... 目录Spring Boot 3 统一返回类设计:从问题到实现一、核心需求:统一返回类要解决什么问题?

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

C++构造函数中explicit详解

《C++构造函数中explicit详解》explicit关键字用于修饰单参数构造函数或可以看作单参数的构造函数,阻止编译器进行隐式类型转换或拷贝初始化,本文就来介绍explicit的使用,感兴趣的可以... 目录1. 什么是explicit2. 隐式转换的问题3.explicit的使用示例基本用法多参数构造

maven异常Invalid bound statement(not found)的问题解决

《maven异常Invalidboundstatement(notfound)的问题解决》本文详细介绍了Maven项目中常见的Invalidboundstatement异常及其解决方案,文中通过... 目录Maven异常:Invalid bound statement (not found) 详解问题描述可