【叶.隨風】

冻龄单身程序猿,前进的路上~

Floyd判圈算法(龟兔赛跑算法)记录

前言

这是在做 142. 环形链表 II 时看到的算法,在这里记录,方便以后复习和学习;

Floyd判圈算法(Floyd Cycle Detection Algorithm),又称龟兔赛跑算法(Tortoise and Hare Algorithm),是一个可以在有限状态机、迭代函数或者链表上判断是否存在环,以及判断环的起点与长度的算法。 – 百度百科

作用:判定链表中是否有环存在以及一些其他的作用,下面会具体说到

基本思想: 既然它的外号叫做“龟兔赛跑算法”,那肯定就要体现出乌龟和兔子的作用了,即一个跑得慢一个跑得快,如果有环的话,那么,兔子肯定是能追上乌龟的,而且追上的时候兔子多跑的路的长度是圈的长度的倍数。以下就用pH指针表示兔子,一次能跑两步(没病走两步……),pT指的是乌龟,一次能跑一步;

例子

这里就以 142. 环形链表 II 这题来记录一下:
题目说道:

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
Note: Do not modify the linked list.

也就是说,如果链表有环存在的话,就要返回第一个入环的节点,比如下图:
这里写图片描述

就应该返回的是2这个节点;而要找到这个入环节点,首先就要先判断是否有环,通过自己实验可以知道,当有环存在的时候,当兔子追到乌龟(在一起了= =|| )的时候:
这里写图片描述

这里写图片描述

这里写图片描述

从追到的这个地方开始,比如这里是节点4,从节点3到4的这个不考虑,然后从1和节点4开始往下遍历相同的步数,当遍历到的是同一个时即为入环结点:
这里写图片描述

则根据龟兔赛跑算法的思想,可以有如下的代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        // 龟兔赛跑算法
        ListNode* pH = head; // 兔子
        ListNode* pT = head; // 乌龟

        while(pH != NULL && pH->next != NULL && pH->next->next != NULL){ // 这里需要判断pH以及pH->next->next是否为NULL,但是如果pH->nextNULL的话就会有空指针异常,所以还要加一个pH->next是否为NULL的判断

            pT = pT->next;
            pH = pH->next->next;

            if(pT == pH){ // 有环,则接下来从龟兔相遇的地方开始作为head2
                // 将tempHead和head2同时移动相同的距离,相等的地方即为入环结点
                ListNode* head2 = pT;
                ListNode* tempHead = head;
                while(tempHead != head2){
                    tempHead = tempHead->next;
                    head2 = head2->next;
                }
                return head2;

            }
        }

        return NULL;


    }
};

总结

  1. 判断是否有环:只需要看pH和pT是否会相遇(遍历到同一个结点)即可,相遇的话就说明 有环;
  2. 确定入环结点:如上所述,这里不再赘述;
  3. 求环的长度:(1) 变量i记录从龟兔相遇的地方head2开始与head同时移动,多少次才相遇,结果再 +1,即为环形链表的结点个数;或者(2)相遇的时候,一定已经在环上了,然后兔子和乌龟只要再次在环上接着跑,再次相遇的时候,跑的快的那个人就比跑的慢的人整整多跑了一圈,所以环的长度也就出来了;
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35056292/article/details/80331053
文章标签: 数据结构与算法
个人分类: 数据结构与算法
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

Floyd判圈算法(龟兔赛跑算法)记录

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭