Floyd判圈算法(龟兔赛跑算法, Floyd's cycle detection)及其证明
2017-04-23 20:02
3071 查看
问题:如何检测一个链表是否有环(循环节),如果有,那么如何确定环的起点以及环的长度。
空间要求:不能存储所经过的的每一个点。
举例:x0=1,xi+1=f(xi),求循环节的起始位置以及循环节的长度。
求解步骤:
使用两个指针slow和fast。两个指针开始时均在头节点处(S点),slow指针(龟)一次向后移动一个一步,fast指针(兔)一次向后移动两步。若存在环,则slow和fast必能相遇;反之若slow到达链表尾时两个指针仍不能相遇,则不存在环。
证明
设头节点S与循环节起始点A之间举例|SA|=m。两个指针在B点相遇,|AB|=n。可知环中的点满足xi=xi+kl,其中l为循环节的长度,也就是说fast比slow多走了整数圈。当i=kl时,满足xi=x2i,这样的i一定存在,得证。
证明
B点的下标 i=kl为l的整数倍。当放到S处的指针移动m到达A时,放在B的指针移动到i+m=kl+m处,于是两个指针相遇。
代码如下:
空间要求:不能存储所经过的的每一个点。
举例:x0=1,xi+1=f(xi),求循环节的起始位置以及循环节的长度。
求解步骤:
1.判断是否有环
使用两个指针slow和fast。两个指针开始时均在头节点处(S点),slow指针(龟)一次向后移动一个一步,fast指针(兔)一次向后移动两步。若存在环,则slow和fast必能相遇;反之若slow到达链表尾时两个指针仍不能相遇,则不存在环。
证明
设头节点S与循环节起始点A之间举例|SA|=m。两个指针在B点相遇,|AB|=n。可知环中的点满足xi=xi+kl,其中l为循环节的长度,也就是说fast比slow多走了整数圈。当i=kl时,满足xi=x2i,这样的i一定存在,得证。
2.计算环的长度
这一步比较简单,让其中一个指针停在B不动,另一个一步一步向前走并记录步数,再次相遇时步数即为环的长度。3.寻找环的起点
其中一个指针在B不动,另一个放到起点S,两个指针同时一步一步移动,则两指针将会在循环节的起点相遇。证明
B点的下标 i=kl为l的整数倍。当放到S处的指针移动m到达A时,放在B的指针移动到i+m=kl+m处,于是两个指针相遇。
代码如下:
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxn = 2e7; int f(int x) { int res = 0; //此处填写递推式,使其走到下一步 return res; } //ori为起点处的值,len为循环节长度,id为循环节起始处坐标,val为循环节起始处的值 bool FloydCycle(int ori, int &len, int &id, int &val)//有环返回true,无环返回false { int slow, fast;//慢指针和快指针 slow = f(ori);//快指针的移动速度是慢指针的2倍 fast = f(f(ori)); int cnt = 1; while(slow != fast && cnt <= maxn)//maxn为链表尾节点 { //快指针的移动速度是慢指针的2倍 slow = f(slow); fast = f(f(fast)); cnt++; } if(slow != fast) return false;//无环 len = 1;//环的长度 slow = f(slow); while(slow != fast) { slow = f(slow); len++; } id = 0; slow = 1; while(slow != fast) { slow = f(slow); fast = f(fast); id++; } val = slow; return true; }
相关文章推荐
- [算法导论]Floyd-Warshall算法及其证明[DP的经典应用]
- Floyd判圈算法(龟兔赛跑算法)【模板】
- Floyd判圈算法(龟兔赛跑算法)
- [转]PLA算法总结及其证明
- 判断一个正整数是否是2的N次方的简洁算法及其证明
- Floyd判圈算法及其证明
- Floyd's Cycle Detection Algorithm
- 迪杰斯特拉(Dijkstra)算法描述及其正确性证明
- 最短路径算法----Floyd-warshall(十字交叉算法证明)
- leetcode202(Floyd判圈算法(龟兔赛跑算法))
- LeetCode 202 Happy Number(floyd判圈算法(龟兔赛跑算法))
- 求二叉树中任意两结点的最近共同祖先的算法及其证明
- 在数组中寻找主要元素的算法及其正确性证明。
- [2016/12/8]happy number:application of Floyd's Cycle Detection Algorithm
- Floyd判圈算法(龟兔赛跑算法)
- LeetCode Linked List Cycle II(Floyd 判圈算法)
- 一道博弈的面试题及其算法正确性证明
- PLA算法总结及其证明
- 关于Floyd-Warshall算法由前趋矩阵计算出的最短路径反映出了算法的执行过程特性的证明
- SGU 455 Sequence analysis(Cycle detection,floyd判圈算法)