Floyd龟兔算法(判圈算法)

目录

1.实质:

2.可以解决解决的问题:

1 .检测是否是环。

2.入环的第一个节点。

3.环的长度。


1.实质:

一种指针算法,使用两种移速不同的指针检测是否有环

2.可以解决解决的问题:

        1.检测是否是环。

        2.环的起点节点。

        3.环的长度。

1 .检测是否是环。

     定义了两个速度不同的指针,在链表上移动,如果链表中有环,快指针先一步进入环然后循环,当慢指针也进入环后,

        两个指针都在环中,且他们速度不同,所以他们早晚会相遇,如果遇到了空节点直接停止循环。

     模板:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        auto *fast=head,*slow=head;
        while(fast != nullptr) {
            slow = slow->next;
            if(fast->next==nullptr) {  //有判空功能,又有条件判断功能。
                return false;
            }
            fast = fast->next->next;
            if(fast==slow) {
                return true;
            }
        }
        return false;
    }
};

对应练习题:leetcode:141. 环形链表

对应题解:https://blog.csdn.net/m0_63442383/article/details/124130803

2.入环的第一个节点。

        1.假设 fast指针走了f步,slow指针走了s步,链表起点和入环的起点的距离是a,环的长度是b。则f和s差了整数倍的环的长度,设这个为k 。

        f = 2s,f=s+k*b,故f=2kb,s=kb,

 

        2.从起点到环入点,再绕环转k圈,走的步数n = a+kb,又因为slow已经走了kb步,故当slow指针再走a步就会到环入点。

        3.设一个指针指向头节点,走a步会与slow指针走a步重合,所让这两个指针同时走,当slow指针与该指针重合时,该节点为入环的第一个节点

 

 复杂度分析:

        时间复杂度 O(N)

        空间复杂度 O(1)

具体题目与题解:142. 环形链表 II(leetcode)_橘子掀开夜晚的博客-CSDN博客

//模板:

  ListNode *detectCycle(ListNode *head) {
         auto *fast=head,*slow=head;
         while(fast != nullptr) {
             slow = slow->next;
             if(fast->next==nullptr) {  //充当节点判空,和循环条件判断
                 return nullptr;
             }
             fast = fast->next->next;
             if(fast==slow) {  
                 auto tmp=head;
                 while(slow!=tmp) {
                     tmp=tmp->next;
                     slow=slow->next;
                 }
                 return tmp;
             }
         }
         return nullptr;
     }

3.环的长度。

        当两个快慢指针相遇时,一个指针固定,另一个指针遍历,当他们再次相遇时,即可求出长度。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值