题解:
方法1:
哈希表:遍历所有节点,每次遍历到一个节点时,判断该节点是否被访问过。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
unordered_set<ListNode*> ans;
while(head != NULL)
{
if(ans.count(head))
return true;
ans.insert(head);
head = head->next;
}
return false;
}
};
方法2:快慢指针
相遇时:
slow指针走过的节点数为: x + y
fast指针走过的节点数: x + y + n (y + z)
又因为fast指针一步走两个节点,slow指针一步走一个节点,所以 fast指针走过的节点数 = slow指针走过的节点数 * 2
即:(x + y) * 2 = x + y + n (y + z)
令n = 1,则X = Z;这就意味着,从头结点出发一个指针,从相遇节点也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针再次相遇的时候就是 环形入口的节点。
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* slow = head;
ListNode* fast = head;
while( fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
{
ListNode *index1 = head;
ListNode *index2 = slow;
while(index1 != index2)
{
index1 = index1->next;
index2 = index2->next;
}
return index1;
}
}
return NULL;
}
};