思路:
判断链表是否有环
使用快慢指针,头节点出发,fast每次移动两个节点,slow就移动一个节点,如果fast和slow相遇的话,就说明链表有环。
问题1:为什么fast每次移动两个节点,slow每次移动一个节点,就一定会在环中相遇,而不是永远错开呢?
fast进入环,如果fast和slow相遇,那么一定是在环中相遇,因为每次移动两者总会产生差距。fast在一直追slow。
2.如何找到在循环中的的判断条件呢?何时跳出?
如果没有环,随着循环,那么fast肯定会先指向为空,当fast或者fast->next为空的时候,那么就跳出循环,说明没有环,返回null。
如果有环,fast就不可能为空,当slow和fast相等时,正式说明有环,此时应该寻找环形链表的第一个入口。
3.如何寻找环的入口呢?
这个有一点点难解释,过程可以看《代码随想录》66页的解释。电子版链接
简略为一个指针从头节点开始,另一个指针为fast和slow相遇节点开始,两个节点同时开始移动,每次都移动一个节点。相遇的位置就是第一个环的入口。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
while(fast != nullptr && fast->next !=nullptr){
slow = slow ->next;
fast = fast->next->next;
if(slow == fast){
ListNode* index1 = fast;
ListNode* index2 = head;
while(index1 !=index2 ){
index1 = index1->next;
index2 = index2->next;
}
return index2;
}
}
return nullptr;
}
};