LeetCode 141. 环形链表 和 142. 环形链表 II

大家好!这篇主要说一下链表里的带环问题
在这里插入图片描述

141. 环形链表

在这里插入图片描述
难度 简单 题目链接
我们先来看一下题目给的例子:
在这里插入图片描述
那么这道题,我们该如何来求解呢?

解决思路:
根据带环链表的形状,我们可以抽象一下:
在这里插入图片描述
我们用快满指针来做,一个fast走两步,一个slow走一步。
在这里插入图片描述
然后我们假设当fast走到环的入口时,slow走到一半:
在这里插入图片描述
当slow进环以后,fast开始进行追赶模式,fast追赶slow:
在这里插入图片描述
如果带环,fast总会有个时间追上slow
在这里插入图片描述
代码如下:
在这里插入图片描述
这道题本身难度不大,关键是我们如何证明呢
为什么快指针每次走两步,慢指针走一步可以
在这里插入图片描述
slow进环开始追击,假设slow进环以后,slow和fast之间的距离是N
在这里插入图片描述
每次追击,距离减1。又因为N它是一个整数,所以总有一次会变为0,会追上

第二个问题:快指针一次走3步,走4步,…n步行吗
我们先分析一下slow走一步,fast走三步:
在这里插入图片描述
slow进环以后,fast开始追击slow。假设它们之间的追击距离为N,环的长度为C
在这里插入图片描述
每次追击,fast和slow之间的距离缩小2。那么根据上面,我们可以进行分析:
在这里插入图片描述
那么N是偶数,它能追上。那么N是奇数呢,它变成-1,-1的意思就是slow和fast之间的追击距离为C-1了
那么我们还按照之前的分析,如果C-1是偶数,那么可以追上。如果C-1是奇数,那么就永远追不上了
那么剩下的步数,也是按照这样去分析。

142. 环形链表 II

在这里插入图片描述
难度 中等 题目链接
示例:
在这里插入图片描述
方法1:公式做法
在这里插入图片描述
我们假设slow和fast在此处相遇。
在这里插入图片描述
那么一个指针在相遇点走,一个指针在开头走。那么它们一定在环的入口相遇
那么我们如何证明这个公式呢
在这里插入图片描述
我们假设前面的长度为L,后面从环的入口到相遇点为X。
那么slow走的距离为:L+X
那么现在有一个问题:slow有没有可能在环里走一圈了,才被fast追上呢
答案是:没这个可能。
因为,fast一次走两步,slow一次走一步。那么fast走的距离是slow走的距离的2倍所以,如果slow走一圈,fast都走两圈了。

那么fast走的距离呢
在这里插入图片描述
这是我们进行的假设。可能有的同学会说fast走的距离是:L+X+C。但是不是这样的,我们来看下面这个例子:
在这里插入图片描述
从这个例子可以看出:fast走到环的入口时,slow走到L的一半。此时,slow每走一步,fast就会绕环一圈。所以fast走的距离:不一定是L+X+C,而是L+N*C+X
然后,根据fast走的距离是slow距离的2倍。所以,2*(L+X)=L+N * C+X,L+X=N * C,L=N*C-X。所以,我们根据这个公式就能得出:一个指针从meet走,一个指针从head走,它们能在环的入口处相遇
在这里插入图片描述
那么我们把代码写一下:
在这里插入图片描述

方法2:断开做法
思路就是:转换成链表相交问题
在这里插入图片描述
这里是相遇的位置,然后我们在相遇的这里把它断开:
在这里插入图片描述
然后我们就可以当作两个链表相交的问题了。

如何断开呢?

struct ListNode* headA=head;
struct ListNode* headB=meet->next;
meet->next=NULL;

实现代码如下:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学代码的咸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值