判断单链表是否有环,判断两个链表是否相交

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

摘要】有一个单链表,其中可能有一个环,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一环。1、如何判断一个链表是不是这类链表?2、如果链表为存在环,如果找到环的入口点?扩展:判断两个单链表是否相交,如果相交,给出相交的第一个点。

有一个单链表,其中可能有一个环,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一环。

问题:

1、如何判断一个链表是不是这类链表?
2、如果链表为存在环,如果找到环的入口点?

解答:

一、判断链表是否存在环,办法为:

设置两个指针(fast, slow),初始值都指向头,slow每次前进一步,fast每次前进二步,如果链表存在环,则fast必定先进入环,而slow后进入环,两个指针必定相遇。(当然,fast先行头到尾部为NULL,则为无环链表)程序如下:

bool IsExitsLoop(slist * head)
{
slist
* slow = head , *
fast = head;

while ( fast && fast -> next )
{
slow
= slow ->
next;
fast
= fast -> next ->
next;
if ( slow == fast ) break
;
}

return ! (fast == NULL || fast -> next ==
NULL);
}

二、找到环的入口点(看下面的附加方法比较好)

当fast若与slow相遇时,slow肯定没有走遍历完链表,而fast已经在环内循环了n圈(1<=n)。假设slow走了s步,则fast走了2s步(fast步数还等于s 加上在环上多转的n圈),设环长为r,则:

2s = s + nr
s= nr

设整个链表长L,入口环与相遇点距离为x,起点到环入口点的距离为a。
a + x = nr
a + x = (n – 1)r +r = (n-1)r + L - a
a = (n-1)r + (L – a – x)

(L – a – x)为相遇点到环入口点的距离,由此可知,从链表头到环入口点等于(n-1)循环内环+相遇点到环入口点,于是我们从链表头、与相遇点分别设一个指针,每次各走一步,两个指针必定相遇,且相遇第一点为环入口点。

程序描述如下:

slist * FindLoopPort(slist * head)
{
slist
* slow = head, * fast = head;

while ( fast && fast -> next )
{
slow
= slow -> next;
fast
= fast -> next -> next;
if ( slow == fast ) break ;
}

if (fast == NULL || fast -> next == NULL)
return NULL;

slow
= head;
while (slow != fast)
{
slow
= slow -> next;
fast
= fast -> next;
}

return slow;
}

附一种易于理解的解释:

一种O(n)的办法就是(搞两个指针,一个每次递增一步,一个每次递增两步,如果有环的话两者必然重合,反之亦然):
关于这个解法最形象的比喻就是在操场当中跑步,速度快的会把速度慢的扣圈

可以证明,p2追赶上p1的时候,p1一定还没有走完一遍环路,p2也不会跨越p1多圈才追上

我们可以从p2和p1的位置差距来证明,p2一定会赶上p1但是不会跳过p1的

因为p2每次走2步,而p1走一步,所以他们之间的差距是一步一步的缩小,4,3,2,1,0 到0的时候就重合了(以5个节点为例)

根据这个方式,可以证明,p2每次走三步以上,并不总能加快检测的速度,反而有可能判别不出有环

既然能够判断出是否是有环路,那改如何找到这个环路的入口呢?

解法如下: 当p2按照每次2步,p1每次一步的方式走,发现p2和p1重合,确定了单向链表有环路了

接下来,让p2回到链表的头部,重新走,每次步长不是走2了,而是走1,那么当p1和p2再次相遇的时候,就是环路的入口了。

这点可以证明的:

在p2和p1第一次相遇的时候,假定p1走了n步骤,环路的入口是在p步的时候经过的,那么有

p1走的路径: p+c = n; c为p1和p2相交点,距离环路入口的距离

p2走的路径: p+c+k*L = 2*n; L为环路的周长,k是整数

显然,如果从p+c点开始,p1再走n步骤(即k*L步,p1又循环了k圈)的话,还可以回到p+c这个点

同时p2从头开始走的话,经过n步,也会达到p+c这点

显然在这个步骤当中p1和p2只有前p步骤走的路径不同,所以当p1和p2再次重合的时候,必然是在链表的环路入口点上。

扩展问题:

判断两个单链表是否相交,如果相交(假设两个链表都不存在环),给出相交的第一个点。

比较好的方法有两个:

一、将其中一个链表首尾相连,检测另外一个链表是否存在环,如果存在(该环就是首尾相连的链表),则两个链表相交,而检测出来的依赖环入口即为相交的第一个点。

二、如果两个链表相交,那个两个链表从相交点到链表结束都是相同的节点,我们可以先遍历一个链表,直到尾部,再遍历另外一个链表,如果也可以走到同样的结尾点,则两个链表相交。

这时我们记下两个链表length,再遍历一次,长链表节点先出发前进(lengthMax-lengthMin)步,之后两个链表同时前进,每次一步,相遇的第一点即为两个链表相交的第一个点。

判断两个链表是否相交 参考:http://blog.chinaunix.net/uid-20754793-id-177773.html 判断两个链表是否相交:(假设两个链表没有)有以下三种方法: 1、判断第一个链表的每个节点是否在第二个链表中 2、把第二个链表连接到第一个后面,判断得到的链表是否,有相交 3、先遍历第一个链表,记住最后一个节点,再遍历第二个链表,得到最后一个节点时和第一个链表 阅读详情

相关推荐

各种方式巧判断链表相交

判断两个链表是否相交 0 问题 判断两个单链表是否相交,(拓展一下就是,如果相交,那么节点在哪?) 1 开场白 因为是单链表,可以看出每个节点只有一个后继节点,所以只存在两个链汇成一个链,不会存在两个链在一点交织,然后分散成两个链,所以问题的求解就与习题4-4,寻找相同后缀的问题基本类似了 2 算法介绍 2.0 数据结构 typedef struct LNode{ int data; LNode *next; }*LinkList, LNode; //且具有头结点! 2.1 利用has

qq_43148207的博客 536

判断链表相交

LeetCode-链表相交

Lion__king的博客 909

判断单链表是否存在判断两个链表是否相交问题详解(转载)

【摘要】有一个单链表,其中可能有一个,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一。1、如何判断一个链表是不是这类链表?2、如果链表为存在,如果找到的入口点?扩展:判断两个单链表是否相交,如果相交,给出相交的第一个点。 有一个单链表,其中可能有一个,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一。 问题: 1、如...

zone 331

判断单链表是否 | 两个单链表是否相交

判断单链表是否 | 两个单链表是否相交 个人语录:时间不负有心人,星光不问赶路人,以顶级好的态度写一篇博客 前些天面试的时候,被三连问: 判断两个单链表是否相交 单链表相交如何找到交点 如何判断单链表是否 当时人就慌了,当然是滑铁卢了,qwq🤦‍♂️ 有了这个你还不会? 文章目录判断单链表是否 | 两个单链表是否相交1. 判断单链表是否1.1 容器判断1.2 快慢指针2. 寻找的连接点3. 获取的长度4. 将带单链表变为普通的单链表5. 判断两个单链表是否相交5.

乐褀的博客 1563

判断单链表是否存在以及两个链表是否相交

有一个单链表,其中可能有一个,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一。如下图: 图1 有链表 问题:如何判断一个链表是不是这类链表?如果链表为存在,如何找到的入口点? 1、判断链表是否存在 思...

chuifuhuo6864的博客 162

判断两个单链表是否相交链表中可能有的情况下)

原文链接:http://www.cppblog.com/zengwei0771/articles/172700.html 题目描述:判断两个单链表是否相交,如果相交,给出相交的第一个点(链表中可能有的情况下) 这里是①判断单链表是否,并求出的入口点;②判断两个链表是否相交链表中无),并求出相交节点 的文章  http://www.cppblog.com/humanchao/a

一颗闪亮的星星 2933

1.11判断两个单链表是否相交

判断两个单链表是否交叉 题目描述: 如上图,这两个链表相交于结点5,要求判断两个链表是否相交,如果相交,找出相交处的结点。 解题思路: 方法一:Hash 法 如上图所示,如果两个链表相交,那么它们一定会有公共的结点,由于结点的地址或引用可以作为结点的唯一标识,因此,可以通过判断两个链表中的结点是否有相同的地址或引用来判断链表是否相交。 方法二:首尾相接法 将这两个链表首尾相连(例如...

bangtuancheng1680的博客 339

链表判断两个单链表是否相交+找到第一个交点|判断两个链表是否

原文;https://blog.csdn.net/fengxinlinux/article/details/78885764 题目:给两个单链表,如何判断两个单链表是否相交?若相交,则找出第一个相交的节点。 这道题的思路和解法有很多,在这把这道题的解法做一个详细的总结。 解这道题之前,我们需要首先明确一个概念: 如果两个单链表有共同的节点,那么从第...

小鱼菜鸟的博客 256

判断两个单链表是否相交?若相交求交点?(单链表

怎样判断单链表是否相交?   如果两个链表相交,则两个链表就会有相同的结点。    方法1. 依次判断第一个链表中的结点是否都在第二个链表中。    方法2. 若两个单链表相交,则从交点之后的链表结点内容是一样的,即两个单链表最后一个结点一定是相同的,我们可以遍历两个结点,判断最后一个元素地址是否相同。    方法3.构,将L2的最后一个结点指向L2的头结点,构成判断L1链表是否有...

zhao_miao的博客 1191

判断单链表是否 | 判断两个单链表是否相交

目录 一.判断单链表是否存在 1.判断一个单链表是否存在 2.寻找的连接点 3.如何获取的长度 4.如何将带单链表变为普通的单链表 二.判断两个单链表是否相交 1.方法一 利用两个相交链表尾节点相等的属性 2.方法二 利用栈 3.方法三 利用 一.判断单链表是否存在 首先我们来看一下,什么叫做单链表中存在,即下图中所示的这种情况。 其中,我们将节点5称为连接点,即这个单链表开始的那个节点。 1.判断一个单链表是否存在 定义两个指针,即快指...

ThinPikachu的博客 980

有苦有乐的算法 --- 可能有也可能无两个单链表判断两个链表是否相交,如果相交返回相交的第一个节点

题目 可能有也可能无两个单链表判断两个链表是否相交,如果相交返回相交的第一个节点。 解析 第一步,判断链表是有链表还是无链表; 如果一个单链表,它一定有一个指向null的尾结点; 如果一个单链表,用两个指针oneStep,twoStep,twoStep一次走两个节点,oneStep一次走一个节点,这两个指针必定会相遇; 此时将twoStep重新遍历,一次走一个节点,oneStep也继续一次走一个节点,二次相遇的时候,这个节点就是入节点。 第二步,判断是否相交; 2-1:一个单链表

一个对Java“一往情深”的后端程序员,对Java生态体系有着浓厚的兴趣与持续的研究。当我不在Java里“内卷”时,我也会探出头来,看看Web技术的广阔天地。希望通过这个博客,与所有同行交流切磋,共同进步。 867

判断单链表是否存在两个单链表是否相交

给出一个单链表,节点结构如下 public class Node{ int value; Node next; } 要求:判断链表是否。若有,返回入的第一个节点;若无,返回null。     快慢指针是链表问题中常用的方法,一个快指针一次走两步,一个慢指针一次走一步。这里利用双指针判断是否。无的情况很简单,fast走得快,如果它遇到null就是无的。注意判断next和...

Daniel_2046的博客 730

判断单链表是否存在判断两个链表是否相交问题详解

转:http://www.cppblog.com/humanchao/archive/2008/04/17/47357.html 有一个单链表,其中可能有一个,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一。 问题: 1、如何判断一个链表是不是这类链表? 2、如果链表为存在,如何找到的入口点? 解答: 一、判断链表是否存在

凡星闪点 981
上一篇: 默认构造函数
下一篇: Linux文件解压
eric_arrow
博客等级 码龄14年 65粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值