[面试题] 判断一个单链表是否有环

来源:互联网 发布:百诚网络 编辑:程序博客网 时间:2024/06/01 08:26

题目:

已知一个单向链表的头指针是 Node* pHead,如何判断该单项链表是否有环路!


Note 1:

看了很多文章中都是直接说定义两个指针,一个每次走一步(PA),一个每次走两步(PB),看最终是否相遇(有环),或者有一个指针指向NULL(无环)。看完之后有点懵,不知道为什么这样就能解决问题。无奈之下只要先证明方法的可行性了。


证明:(反证法)

如果链表中没有环,则走每次两步的指针(PB)肯定会先指向NULL;

如果链表中有环,并且能相遇(很显然一定在环中相遇),设在进入环之前有m个节点,环中有n个节点,PA在走x步之后与PB相遇,很容易列出公式:

(x - m) % n = (2*x - m) % n,

也就是

(2*x - m) - (x - m) = k * n (k为某一常数) 

化简得

x = k * n (k可以在保证k*n>m的情况下任意取值)

很显然该方程有解,所以如果有环肯定相遇。


Note 2:

虽然证明的结果表示方法是无误的,但是还是不能理解!悲剧.....

突然看到有人说这其实就是一个追击问题,我的思路一下子就打开了。

很显然,如果有环,肯定PB先进入环,那么PA进入环的时候有可能恰好与PB相遇(perfect,之后就不用说了),如果PA在进入环的时候没有与PB相遇,那说明PB到PA是有一定的距离的(相隔的节点数,设为N),那么PA每次走一步,PB每次走两步,也就是说PB每次想PA靠近距离1,那么只要在走N次,肯定相遇,到此豁然开朗!(对着答案分析都这么费劲,有点淡淡的忧桑~~~)


代码:

太简单了,就不写了!

原创粉丝点击