检查链表是否有环,带数学推导

博客已经搬家!请前往http://gqqnbig.me/?p=181 阅读本文。

推导

给定下列列表(4指回2),若有快慢两个指针,慢指针每次前进一步,快指针每次前进两步,求两指针何处相遇?

1-2-3-4
  |___|

解:

设两指针前进n次。n必定大于等于1。

In[1]:=Reduce[Mod[n
– 1, 3] == Mod[2n – 1, 3], n, Integers]Out[1]:=c1∈Z∧n=3c1

然后寻找满足上述条件(Out[1])的最小的n。

In[2]:=FindMinimum[{3c,
3c > 1, Element[c, Integers]}, c]Out[2]:={3.,
{c -> 1}}

所以n=3,即slow、fast两指针在4处相遇。

一般化:给定一个单链表,前面非循环部分有a个节点(长度为a),后面循环部分有l个节点(长度为l)。求快慢两指针走多少次后相遇?

同理,设前进n次后相遇。(n>a)

快指针的位置=慢指针的位置

??∴(2n?a)%l=(n?a)%l2n?a≡n?a(modl)n≡0(modl)n=kl(k?0)公式1公式2

公式1是同余表达式,读作2n-a和n-a在模l下同余,≡不是全等的意思,mod不是5
mod 3=2的意思。公式2应用同余的性质,等号右边移到左边抵消掉。(注意到(modl)前的空格没有?mod
l表示对前面等号的左边和右边同时取余数)

所以n是l的倍数。n不一定等于l,因为n必须大于a,而a与l的关系未知。

因为n≠l,所以2n?n=kl≠l。这里就证明了Bluefeather说的“fastVal
– slowVal equals the size of the loop”[1]是错误的。

能否求出l的具体值呢?答案是可以的。根据GoCalf[2],两指针相遇后,快指针暂停慢指针继续走,两指针第二次相遇时,慢指针走的次数就是环长。

求环长

给定任意带环链表,快慢指针相遇时走的次数为该带环链表的环长。

求非循环长度

已知环长后,可以求非循环部分的长度a。

获取甲乙两个慢指针,甲先走l次,然后甲乙一起走。因为甲乙步长相同,他们之间始终保持l的差距。当乙第一次进入循环节时,由于甲乙差距为l,l为循环节长度,所以甲跟乙相遇。这时乙所走的步数就是a。

1. Bluefeather. Share
my O(n) complexity and constant space code. Keep the original list. Any comments
. . 2014-12-12 [2015-01-08].
2. GoCalf. 检测单向链表是否存在环.
. 2011-10-14 [2015-01-08].
时间: 2024-11-09 06:09:32

检查链表是否有环,带数学推导的相关文章

Java数据结构-线性表之链表应用-检测链表是否有环

??如何检测一个链表是否有环?这个是一个出现频率较高的面试题. ??如下是一个含有环的链表. (图片来自http://www.nowamagic.net/librarys/veda/detail/2245 一个有很多关于数据结构的文章的网站,还有其他的资料,可以看看) 我这里解题的方法有三种: 快慢指针方法:两个速度不一样的指针遍历总会相遇: 利用环的顶点数和边相等的关系: 两个指针遍历判断步数是否相等. ??为了实现检查链表是否含有环的情况,我们需要先构建出一个含有环的链表. ??于是乎我在之

判断两个链表是否相交(带环)

解决方案: 1.找出链表1的环入口节点a1,链表2的环入口节点a2; 2.如果a1=a2; 说明两个链表可能在入环之前或者入环第一个节点相交:将a1,a2作为两个链表的最后一个节点,转化为不带环的链表相交:其实在这种情况下已经说明两个链表已经相交了. 3.如果a1!=a2;以a1为基准节点进行while循环,如果在循环中找到跟a2相同的节点,说明两个链表相交:如果没找到,说明不相交. #如果1个链表不带环,1个链表带环:则两个链表必不相交:

如何判断单链表是否存在环

原文:http://blog.csdn.net/liuxialong/article/details/6555850 如何判断单链表是否存在环 给定一个单链表,只给出头指针h: 1.如何判断是否存在环? 2.如何知道环的长度? 3.如何找出环的连接点在哪里? 4.带环链表的长度是多少? 解法: 1.对于问题1,使用追赶的方法,设定两个指针slow.fast,从头指针开始,每次分别前进1步.2步.如存在环,则两者相遇:如不存在环,fast遇到NULL退出. 2.对于问题2,记录下问题1的碰撞点p,

如何判断单链表是否存在环 & 判断两链表是否相交

给定一个单链表,只给出头指针h: 1.如何判断是否存在环? 2.如何知道环的长度? 3.如何找出环的连接点在哪里? 4.带环链表的长度是多少? 解法: 1.对于问题1,使用追赶的方法,设定两个指针slow.fast,从头指针开始,每次分别前进1步.2步.如存在环,则两者相遇:如不存在环,fast遇到NULL退出. 2.对于问题2,记录下问题1的碰撞点p,slow.fast从该点开始,再次碰撞所走过的操作数就是环的长度s. 3.问题3:有定理:碰撞点p到连接点的距离=头指针到连接点的距离,因此,分

链表中的环

判断链表是否有环,定义指针一快(走2部)一慢(走1部),相遇即有环. bool isCircle(listNode* head){ if(NULL == head) return false; listNode* slowNode = head->next; if(NULL == slowNode) return false; listNode* fastNode = head->next; while(fast != NULL && slow != NULL){ if(fas

判断链表是否有环及环入口点的求法(Linked List Cycle II )

分为两步 第一步 还是利用快慢指针,如果有环的话在利用快慢指针终会相会于一个节点. 第二步.然后从这节点出发每次出发走一步,同时从根节点出发每次出发也走一步则他们两个指针相遇的地方就是环的入口. 第一步好解释那么第二步是为什么呢? 网上有很多解法大都是从数学的角度来分析,有公式也有推算很不直观,我从图形的角度来看的话就相对理解起来简单很多. 将图摊开成一条线,假设我们有环而且假设快指针就多走了一圈就与慢指针相遇了(多走n圈其实也是一样的,画出图来也不难理解,只是画起来麻烦索性就以一圈来代表) 红

判断单链表是否有环相关问题(转载加总结)

给定一个单链表,只给出头指针h: 1.如何判断是否存在环? 2.如何知道环的长度? 3.如何找出环的连接点在哪里? 4.带环链表的长度是多少? 解法: 1.对于问题1,使用追赶的方法,设定两个指针slow.fast,从头指针开始,每次分别前进1步.2步.如存在环,则两者相遇:如不存在环,fast遇到NULL退出. 2.对于问题2,记录下问题1的碰撞点p,slow.fast从该点开始,再次碰撞所走过的操作数就是环的长度s. 3.问题3:有定理:碰撞点p到连接点的距离=头指针到连接点的距离,因此,分

8.判断单链表是否有环(6形状)?如何找到环的“起始”点?如何知道环的长度?

8.判断单链表是否有环(6形状)?如何找到环的“起始”点?如何知道环的长度? 思路: 注意分析题意,题意并非是说单链表完全成O形状的环,而是说单链表成6形状的环. 首先判断是否有环:为此我们建立两个指针,从Head一起向前跑,一个步长为1,一个步长为2,用 while(直到步长2的跑到结尾){检查两个指针是否相等,直到找到为止.} 来进行判断. 原因是,在这场跑步中,结束循环有两种可能,其一是原来无环,所以2先跑到结尾,因为2比1快,二者不可能相等.其二是原来是有环的,因为这场赛跑永远没有z终点

最大熵模型中的数学推导

最大熵模型中的数学推导 查看原文,点击这里 0 引言 写完SVM之后,一直想继续写机器学习的系列,无奈一直时间不稳定且对各个模型算法的理解尚不够,所以导致迟迟未动笔.无独有偶,重写KMP得益于今年4月个人组织的算法班,而动笔继续写这个机器学习系列,正得益于今年10月组织的机器学习班. 10月26日机器学习班第6次课,身为讲师之一的邹博讲最大熵模型,他从熵的概念,讲到为何要最大熵.最大熵的推导,以及求解参数的IIS方法,整个过程讲得非常流畅,特别是其中的数学推导.晚上我把他的PPT 在微博上公开分