博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
判断一个链表是否有环
阅读量:6243 次
发布时间:2019-06-22

本文共 1911 字,大约阅读时间需要 6 分钟。

思路:如果开始有两个指针指向头结点,一个走的快,一个走的慢,如果有环的话,最终经过若干步,快的指针总会超过慢的指针一圈从而相遇。

  如何计算环的长度呢?可以第一次相遇时开始计数,第二次相遇时停止计数。

  如何判断环的入口点?碰撞点p到连接点的距离=头指针到连接点的距离,因此,分别从碰撞点、头指针开始走,相遇的那个点就是连接点。

  当fast与slow相遇时,show肯定没有走完链表,而fast已经在还里走了n(n>= 1)圈。假设slow走了s步,那么fast走了2s步。fast的步数还等于s走的加上环里转的n圈,所以

有:2s = s + nr。因此,s = nr。    

  设整个链表长为L,入口据相遇点X,起点到入口的距离为a。因为slow指针并没有走完一圈,所以:a + x = s,带入第一步的结果,有:a + x =

nr = (n-1)r + r = (n-1)r + L - a;即:a = (n-1)r + L -a -x;

  这说明:从头结点到入口的距离,等于转了(n-1)圈以后,相遇点到入口的距离。因此,我们可以在链表头、相遇点各设一个指针,每次各走一步,两个指针必定相遇,且相遇第一点为环入口点。

 

判断是否有环

 

bool hasCycle(ListNode *head) {        ListNode *fast(head), *slow(head);        while(fast && fast->next)        {            fast = fast->next->next;            slow = slow->next;            if(fast == slow)                return true;        }        return false;    }

 

 

计算环的长度

int loopLength(ListNode *head){    if(hasCycle(head) == false)        return 0;    ListNode *fast = head;    ListNode *slow = head;    int length = 0;    bool begin = false;    bool again = false;    while( fast != NULL && fast->next != NULL)    {        fast = fast->next->next;        slow = slow->next;        //超两圈后停止计数,挑出循环        if(fast == slow && again== true)            break;        //超一圈后开始计数        if(fast == slow && again == false)        {                        begin = true;            again= true;        }        //计数        if(begin == true)            ++length;            }    return length;}

 

//求环的入口结点

ListNode* findLoopEntrance(ListNode *head){    ListNode *fast = head;    ListNode * slow = head;    while( fast != NULL && fast->next != NULL)    {        fast = fast->next->next;        slow = slow->next;        //如果有环,则fast会超过slow一圈        if(fast == slow)        {            break;        }    }    if(fast == NULL || fast->next == NULL)        return NULL;    slow = head;    while(slow != fast)    {        slow = slow->next;        fast = fast->next;    }    return slow;}

 

转载地址:http://ylsia.baihongyu.com/

你可能感兴趣的文章
Delphi-IOCP 共同学习研究群号 320641073
查看>>
sql2008中已存在已有数据表修改主键为自增不让更改的解决方案
查看>>
控件路径自定义控件遇到的两个小问题
查看>>
【BZOJ】2648: SJY摆棋子 & 2716: [Violet 3]天使玩偶(kdtree)
查看>>
数据仓库与数据挖掘的一些基本概念
查看>>
Android学习系列(23)--App主界面实现
查看>>
jquery validate的漂亮css样式验证
查看>>
OAF_解决OAF与Windows版本不兼容黑屏
查看>>
如何让编码更加的标准
查看>>
阿里云收集服务器性能指标的python脚本
查看>>
Docker源码分析(一):Docker架构
查看>>
Android开发之在子线程中使用Toast
查看>>
(第三天)函数
查看>>
Git 学习笔记--Git下的冲突解决
查看>>
poj 2955 Brackets(区间dp)
查看>>
jQuery选中该复选框来实现/全部取消/未选定/获得的选定值
查看>>
武汉Uber优步司机奖励政策(8月31日~9月6日)
查看>>
javascript小技巧:同步服务器时间、同步倒计时
查看>>
JUnit4.8.2来源分析-2 org.junit.runner.Request
查看>>
你觉得你在创业,但其实你可能只是在做小生意而已 制定正确的计划 创业和经营小企业之间的差异...
查看>>