力扣141环形链表问题|快慢指针算法详细推理,判断链表是否有环|龟兔赛跑算法
目录
1.假设有环并且一定会相遇,那么一定是在环内相遇,且是快指针追上慢指针。
2.有环就一定会相遇吗?快指针是每次跳两步,有没有可能把慢指针跳过去?
前言:
在环形链表问题中,使用快指针和慢指针的原因在于这种方法能够高效地检测链表是否包含环。这种方法也称为“龟兔赛跑算法”,具体来说,让快指针每次移动两步,慢指针每次移动一步,可以保证在存在环的情况下两指针最终会相遇。
一、算法推导:
1.假设有环并且一定会相遇,那么一定是在环内相遇,且是快指针追上慢指针。
一定会在环内相遇:
设慢指针速度为v,则快指针速度为2v,
走了相同时间t时,
满指针走的路程:s=vt,则快指针为2s(2vt),
因此没有环不可能相遇,相遇的话必定在环内。
快指针追上慢指针:
慢指针不可能追上快指针,因为速度没有快指针快,永远被落在后面。
只有等快指针跑下一圈时遇上慢指针。就像我们跑800m的时候,有些跑得快的同学可以在跑第二圈的时候与有些跑得慢还在跑第一圈的同学相遇。
因此相遇时的情景一定是这样:
2.有环就一定会相遇吗?快指针是每次跳两步,有没有可能把慢指针跳过去?
建立认知:
如图,当快指针在慢指针后面,且距离1的时候,下一回合就可以相遇。
那当快指针在慢指针后面,且距离2、3、4、5、...、n时呢?
建立认知:
如图,每走一回合,两者之间的距离会-1。
也就是说,不断的走,n-1-1-1-1-1........两者距离一定会减到1。
切入角度1:
那么就会发生如下图情况,两指针相遇。
切入角度2:
不断的走,n-1-1-1-1-1........两者距离一定会减到0。此时此刻,两指针相遇
3.那一定会在一圈内相遇吗?
设一圈的长度为c,
入环后两指针的距离为n。则n<=c。
每一回合n-1,最坏情况下,当n=c时,一共需要c个回合,n才为0,两个指针才能相遇。c个回合,慢指针刚好走一圈。因此,一圈内肯定会相遇。
二、开始做题:
1.注意题目的条件,先做特殊情况处理
if(head==null || head.next==null){
return false
}
2.定义快慢指针和注意判断语句
如果代码中没有环,快指针遍历到终点时会指向空,
又因为快指针每次要连跳两格,所以要判断一下fast.next,避免空指针异常
3.完整代码:
public class Solution {
public boolean hasCycle(ListNode head) {
if(head==null || head.next==null){
return false;
}
ListNode fast=head;
ListNode slow=head;
while(fast!=null && fast.next!=null &&slow!=null){
fast=fast.next.next;
slow=slow.next;
if(fast==slow){
return true;
}
}
return false;
}
}
三、为什么快指针每次走两步,而不是三步或更多?
1.效率和正确性平衡:
如果快指针每次走三步或更多步,可能会跳过慢指针,使得两者在环内无法相遇,或者需要更多的时间和步骤来相遇,算法的效率和简单性会下降。
2.两步最优:
前人通过大量实际问题和理论证明,快指针每次走两步,慢指针每次走一步,既能保证在环内快速相遇,又不会跳过相遇点。
原文地址:https://blog.csdn.net/weixin_71246590/article/details/140701970
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!