题意:给定一个链表,若该链表为环形链表,则返回链表入环的第一个节点,若不是,则返回NULL。
思路:假设链表为环形链表,设两个指针:快指针与慢指针。其中,快指针一次走两个节点,慢指针一次走一个节点。因为链表为环形链表,则两个指针一定会在某一刻于环形中的某一点相遇。则有如下示意图:
其中,a为链表头节点到环形入口的距离,b为环形入口到相遇点的距离,c为相遇点到环形入口的距离。
设相遇时,慢指针走了n次环形,快指针走了m次环形。
则慢指针总共走了,快指针走了
。
因为快指针一次走的距离是慢指针的两倍,所以有:
化简得
所以若有两个指针同时从头节点和相遇点出发的话,两个指针会在环形入口相遇。
代码:
/**
* 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 *slow = head, *fast = head;
while(slow && fast)
{
slow = slow->next;
fast = fast->next;
if(fast == NULL) return NULL;
fast = fast->next;
if(slow == fast)
{
while(slow != head)
{
slow = slow->next;
head = head->next;
}
return head;
}
}
return NULL;
}
};