单链表是否存在环的检测(快慢指针法)

  面试时,遇到的问题。一个单链表,判断是否存在环?

  当时从循环队列中想到:如果判断队列是空或者满是用头尾指针相等判断。那么,这里我也想到类似这样的解决办法,用相遇问题的解法来算。设一个快指针,一个慢指针。有环的情况要不是本来就是循环队列,要不就是在尾部存在环。而且一旦指针进入环,就再也出不来了。所以只要是入环就成为了追及问题。当时,我想的比较简单,直接慢指针走一步,快指针走两步,这样相遇得较快,并且相遇概率也比较大,不会出现跳过的情况。但是面试官接下来问了一个问题,如果走三步,行不行?四步呢?n步呢?当时我没想出好的解释,回来查了些资料,找到了一些解释。

判断单链表里面有没有环     http://www.cnblogs.com/zhyg6516/archive/2011/03/29/1998831.html

算法面试题(1) - 有环链表   http://www.cnblogs.com/shawn-zhou/archive/2008/11/26/1341307.html

链表面试题之有环链表问题 http://kb.cnblogs.com/page/52054/

单向链表存在环的判断        http://blog.csdn.net/feike2008/article/details/5615039

  这里就涉及到了两个指针a,b的步数选择问题,不妨从追及问题开始算。假设指针p为慢指针,q为快指针,那么p的步数为a,q的步数为b,在开始时,q在环中领先p指针h步,那么经过x次迭代后,p,q相遇,有

ax = h+bx-yc;

其中环的长度为c,y为相遇时q领先了p指针y圈。化简为

(b-a)x = h + yc; =====> x = (h + yc)/(b-a);

此时,可以看出h和cy都是随机可取的,这里要保证x为有限值,且为正整数,应有b-a整除h+yc,所以b-a = 1;满足条件,即无论a,b为什么数,当他们相差1的时候总能追上来判断环但是时间复杂度是不一样的。

举个例子:c = 8,几个节点为0~7;

sp = 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0

fp = 0 3 6 1 4 7 2 5 0 3 6 1 4 7 2 5 0

只要将两者相互移动,就能模拟追及问题。

sp = 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0

fp = 3 6 1 4 7 2 5 0 3 6 1 4 7 2 5 0 3

上面的例子就可以看出,在该种情况下,a = 1,b = 3是不成立的。

不过从简单和速度上来说还是选1,2较好。还有延伸的问题就是找到入口,测环的长度等等,暂时没想到以后再写。

如有错误请在评论中指出,勿喷!多谢多谢!

原文地址:https://www.cnblogs.com/putuotingchan/p/4042789.html