环路检测
题目地址:https://leetcode-cn.com/problems/linked-list-cycle-lcci/
题解解释的很棒,用数学思维推倒,然后就可以很简单的编写代码了。
第一个想出这种解法的人是个鬼才。
这里自己总结一下:
- 先引用一张图片
- 看图分析
快指针每次移动两个节点位置,慢指针每次移动一个节点位置。
当慢指针在c这个位置和快指针相遇的时候,慢指针移动了m + y 个节点位置。而快指针移动了m + nx + y个位置。(n为环的周长,x为>= 1的整数)
又因为快指针的移动位置时慢指针的两倍,所以可以列出等式:2*(m + y) = m + nx + y。
根据上面等式,可以得到:m = nx - y = n(x-1) + n - y (因为n是周长,写成这种格式是为了更好的察觉指针的位置,循环了x-1圈,最后停留在在n-y处)
这时候让一个新的指针指向a这个位置,而快指针和慢指针在c相遇,这里快指针就可以舍弃了,以慢指针的移动单位,同时移动慢指针和新创建指向a位置的指针。
根据图片可以看出,新指针从a到b移动了m的距离,因为上面我们得出了:m = n(x-1) + n - y,所以慢指针从c位置移动n(x-1) + n - y个位置,应该到y+n(x-1) + n -y ,因为n(x-1)是走的圈数,所以这里慢指针也刚好走到b这个位置,也就是入环的节点位置。
- 代码实现