快慢指针
相关证明
Th 1.在有环的链表中,快慢指针一定相遇。
证明:如果链表中有环,快慢指针一定在环内相遇。这可以看做是,快指针追赶慢指针的过程。
- 如果快指针在与慢指针差一步,则在下一步中,快指针前进两步,慢指针前进一步,两个指针相遇。
- 如果快慢指针相差两步,在下一步中,快指针前进两步,慢指针前进一步,两个指针相差一步,转为第一种情况。
- 如果快慢指针相差N步,经过N-1步的追逐,转换为第一种情况。
因此在有环的链表中快慢指针必然相遇。
2.Th 2:慢指针进入环之后,快指针最多比慢指针多绕一个圈。
证明:当慢指针进入环时,假设快慢指针相差m步,则经过m步,快指针必然能追上慢指针。因为0<=m小于环的长度,所以,慢指针进入环后,快指针最多比慢指针多绕一个圈。
环长度的计算
当快慢指针p,q在环内第一次相遇后,两者之间的距离为0(也是链表的长度)。因此只需要让快慢指针继续从该点出发,直到下一次相遇,中间进行的操作次数就是环的长度。
寻找连接点
根据Th 1与Th 2,设慢指针进入到环中时的点为c,这个点即为连接点。设此时快指针p距离慢指针q有m步。则经过m步之后,p与q在p_q点相遇。
此时头结点head从链表头部出发,每次走一步。设链表中无环部分长度为a,p_q距离连接点c的距离为m,环的其余部分长度为n。
当快慢指针第一次相遇时,
慢指针走了S步:
S=a+m
此时快指针走了2S步:
2S=a+k*(m+n)+m
所以
2a+2m=a+k*(m+n)+m
a=(k-1)*(m+n)+n
从上式可以看到,k圈+n就是入环点了。为了找到这个入环点,让head指针从初始位置出发,一次走一步,慢指针从相遇点p_q出发,一次走一步,两个结点相遇的地方就是连接点。
例题
待补充