1.用set,保存结点的指针
2.遍历链表,插入set之前查找set
/**
* 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) {
if(head == nullptr || head->next == nullptr)
return nullptr;
set<ListNode*> s;
while(head)
{
if(s.find(head) != s.end())
return head;
s.insert(head);
head = head->next;
}
return nullptr;
}
};
思路2:快慢指针
// head
// 1 -- 2 -- 3 -- 4 -- 5
// | |
// 7 --------6 fast和slow在6相遇
//设 2,3段为a, 4,5,6为b, 7,3为c
//slow = a + b
//fast = a + b + c + b
//2*slow = fast
//所以 a = c
所以再让fast = head,slow在meet的地方出发,就会在3相遇
/**
* 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;
ListNode* meet = nullptr;
while(fast)
{
slow = slow->next;
fast = fast->next;//先向前走一步
if(!fast)
return nullptr;
fast = fast->next;//在向前走一步
if(fast == slow)
{
meet = slow;
break;
}
}
if(!meet)
return nullptr;
while(head&&meet)//分别从起点和相遇点 以同样的速度前进
{
if(head == meet)
return head;
head = head->next;
meet = meet->next;
}
return nullptr;
*/
//这样写比上面的写法运行快一些
if(head == nullptr || head->next == nullptr)
return nullptr;
ListNode* fast = head;
ListNode* slow = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
break;
}
fast = head;
while(fast &&slow)
{
if(fast == slow)
return fast;
slow = slow->next;
fast = fast->next;
}
return nullptr;
}
};