判断单链表是否有环并找到循环头结点
和两个速度不同的人跑步一个道理
如果跑道是直的,快的人会直接到达终点,如果跑道有环,一直跑下去,两个人终会相遇(爱情不就来了吗)
两个指针从第一个节点开始走
A指针一次走一步,B指针一次走两步
若链表没有环:B会比A先到达终点(NULL)
若有环:A和B会相遇
思考:那B有没有可能跨过A呢
首先,你要明白,当A还没到环内,B已经到环内了,A到环内时,
要么与B相遇, 要么在循环头结点,B在环内,B跑得快,B是去追逐A的。
看图:如果B在A的后面一步
如果B在A的后面两步:
咱就是说,B在A后面, B每次之比A快一步,每次只多追一步,怎么会错过呢
再思考,A有没有可能跑两圈
再看图:
这就是最恶劣的情况啦,B比A慢了整整一圈,走走看,A会不会跑超过一圈呢。
我相信你懒得跑,答案是不会的,并且他们会在这里相遇
最后,如果环外长度很长很长很长,B可能会多跑很多圈
到此,我们就可以解决第二问啦
假设,环外有y个结点,环内有x个结点,他们在m相遇,B跑了n圈
慢指针走的步数: y+m
快指针走的步数:2y+2m
快指针还可以这样计算:y+nx+m
2y+2m=y+nx+m
得到
y=(n-1)x+(x-m)
x-m 代表着相遇结点到头结点的步数
y=(n-1)x+(x-m)这个等式的意思是,x的整数倍步数+相遇结点到头结点的步数=环外结点长度
由此可知:相遇时设一个指针A,单链表开始处设一个指针A,一起跑,再相遇的地点就是循环头结点了
完结。