一、给定一个链表判断是否有环
1.解题思路
我们可以定义一个快慢指针,让他们从头开始走,如果最后快指针追上慢指针说明有环,如果快指针走到NULL,则说明环不存在。
2.拓展问题
快指针一次走3步、4步.....n步也可以判断吗?
如果要解决这个问题,我们就不得不了解一下原理了。如果链表带环的话,快指针先进环,慢指针后进环,最好的情况就是在慢指针刚进环时刚好跟快指针相遇,最坏的情况就是快指针跟慢指针中间相差的路程为环的路程,两指针每走一次距离就缩短一步,最后总会相遇。
那么我们以一次走3步为例,假设快指针一次走3步,也就是说进入环后两指针每走一次距离就缩短两步,但是也会出现错过的情况,即两指针之间的距离N为奇数的时候就会错过,N为偶数则相遇。错过后两指针继续在环中运动,两指针的距离变为环的长度C-1,此时如果C-1为偶数则可以相遇,如果为奇数则永远无法相遇。因此要想知道快指针一次走3步能不能判断,也就是判断N为奇数以及C-1为奇数能否同时存在。
这里假设在未进环之前的路程为L,我们要通过已有的数据来找等式表达式。
在慢指针将要进环时:
慢指针走过的路程:L
快指针走过的路程:L+x*C+C-N
快指针走过的路程是慢指针走过路程的三倍
3*L=L+(x+1)*C-N
2*L=(x+1)*C-N
这里我们使用反证法假设N为奇数以及C-1为奇数能同时存在,带入到式子中得到:
偶数=偶数-奇数,显然是不成立的,因此快指针一次走3步也可以判断是否为环。
二、给定一个链表返回入环的第一个节点
1.思路一:定义两个指针分别从快慢指针相遇的节点与头节点开始走,相遇的位置为入环的第一个节点
在这里我们假设在进环之前的路程为L,慢指针与快指针相遇时慢指针在环中走的路程为N,环的路程为C。
相遇时慢指针走过的路程:L+N
快指针走过的路程:L+x*C+N
根据快指针走过的路程是慢指针的两倍得出:L+N=x*C,x至少为1因此无论x为多少,L+N一定是整数圈,所以两个指针在头节点与快慢指针相遇的节点处同时走,相遇的位置就是入环的第一个节点。
2.思路二:在快慢指针相遇的下一个节点重新定义一个节点newhead,并将相遇节点断开,然后使用相交链表就可以得到第一个入环节点
这里再讲一下相交链表的思路,就是分别求出两条链表的长度,然后让长的那条先走多出来的部分,最后两条链表再同时走,第一个链表地址相等的节点就是第一个相交的节点,也就是第一个入环节点。