链表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的相遇点计算,这里以相遇点做示范:

struct ListNode*cur2=meet->next;
int count=1;
while(cur2!=meet){
cur2=cur2->next;
count++:
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值