当前位置:   article > 正文

链表OJ(环形链表)

链表OJ(环形链表)

一、链表带环的判断

当给定一个链表的时候,如何判断其是否带环呢?这里我们将以力扣上的一道OJ题为例:

(题目链接:https://leetcode.cn/problems/linked-list-cycle/ 感兴趣的可以看看)

1.解决思路

链表的带环问题比较传统的解法是使用快慢指针,当快指针与慢指针能够相遇,则说明链表中带环。所以我们可以写出如下的代码:

在解决一个问题的时候,我们往往要了解它的原理,这种解法是偶然的还是具有一定的逻辑?

下面我们将来探讨:

2.思路的数学证明

这里定义了两个指针,一个为fast,每次走两步,一个为slow,一次走一步。若链表不成环,则它们没有相遇的可能,若链表成环,我们将来细讲:

开始时,状态如下:

                                                        当slow入环后,转变成了追及问题:

每次循环,两者之间的间距减1:N,N-1,N-2,…………2,1,0,最终fast=slow

3.思考:其他的步调是否能够得到相同的结果呢

快指针走3步,4步……n不行吗?

这里我们以快指针走三步为例,进行数学分析

具体分析如下图:

可以证明b这种情况并不存在

我们也可以通过代码来运行一下:

可以看到这种步调也是跑过了的,感兴趣的可以尝试推导一下其他的步调。

二、环的入口节点问题

上面我们讲到了如何判断链表是否带环,下面我们要来研究一下环的入口节点在哪,这里我们以另一道OJ题为例:

(题目链接:https://leetcode.cn/problems/linked-list-cycle-ii/description/

 1.解决思路

我们以slow走一步,fast走两步为例,这个问题的固有思路是设定一个meet指针,meet指针为fast和slow相等时的那个节点,再设置一个临时指针cur指向链表的头部,cur和meet同时向后走,当两者相遇时,相遇时的节点即为环的入口节点。

2.思路的数学证明

3.环的长度

环的长度即为从环中的某个点再次回到该点之间的距离。我们在上面已经求得了环的入口点,可以用入口点计算,也可以用fast与slow的相遇点计算,这里以相遇点做示范:

  1. struct ListNode*cur2=meet->next;
  2. int count=1;
  3. while(cur2!=meet){
  4. cur2=cur2->next;
  5. count++:
  6. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/894656
推荐阅读
相关标签
  

闽ICP备14008679号