链表是否有环
```cpp []
//快慢指针1:推荐这种,简洁好理解,第二种不好理解
class Solution {
public:
bool hasCycle(ListNode *head) {
if(!head || !head->next) return false;
ListNode* fast = head;
ListNode* slow = head;
while(fast->next && fast->next->next){
slow = slow->next;
fast = fast->next->next;
if(fast == slow) return true;
}
return false;
}
};
```
```cpp []
//快慢指针2
class Solution {
public:
bool hasCycle(ListNode *head) {
if(head == nullptr || head->next == nullptr) return false;
auto *fast_2 = head, *slow_1 = head;
while(fast_2)
{
if(fast_2->next && fast_2->next->next) //相&的前后顺序换一下会出报可能指向空节点
{
slow_1 = slow_1->next;
fast_2 = fast_2->next->next;
}
else return false;
if(fast_2 == slow_1) return true;
}
return false;
}
};
```
```cpp []
//set法
class Solution {
public:
bool hasCycle(ListNode *head) {
if(head == nullptr || head->next == nullptr) return false;
set<ListNode*> only_set;
while(head)
{
if(only_set.count(head)) return true;
else
{
only_set.insert(head);
head = head->next;
}
}
return false;
}
};
```
返回链表入口
这个还是有点东西的,先快指针走两步,慢指针走一步。若有环,则一定会相遇,第一次遇见后,快指针回到头,开始跟慢指针,一步一步的走,直到再次相遇,它们的位置即为环形链表入口。
```cpp []
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
if(!head || !head->next) return nullptr;
ListNode* fast = head;
ListNode* slow = head;
while(fast && fast->next){
slow = slow->next;
fast = fast->next->next;
if(fast == slow){ //相遇,fast回到开头
fast = head;
while(fast != slow){ // 都一步一步走,知道再次遇上,这时的位置即为环形链表入口
fast = fast->next;
slow = slow->next;
}
return fast;
}
}
return nullptr;
}
};
```