142.环形链表II
**题目描述:**给定一个链表的头节点,返回链表开始入环的第一个节点。(无环返回 null)
视频讲解
文章讲解
思路:
- 快指针一次走两步,慢指针一次走一步
- 有环:慢指针入环,快指针一步一步追上慢指针,一定会在环里相遇
- 无环:快指针先走到 尾节点 或 nullptr
- 找入环点:
- 不妨设入环点在x处,环长为l,考虑两个时刻(如图)
- pre从头节点出发,cur从相遇点出发,均一次走一步,将在入环点相遇
/**
* 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 && fast->next) {
fast = fast->next->next;
slow = slow->next;
if(fast == slow) {
ListNode* temp1 = slow;
ListNode* temp2 = head;
while(temp1 != temp2) {
temp1 = temp1->next;
temp2 = temp2->next;
}
return temp1;
}
}
return nullptr;
}
};
// 双指针
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
// 追及问题 相遇时多走了n个环的长度
int count = 0;
ListNode* fast = head;
ListNode* slow = head;
while (fast && fast->next) {
fast = fast->next->next;
slow = slow->next;
count++;
if (fast == slow) break;
}
if (!fast || !fast->next) return NULL;
fast = head;
slow = head;
while (count--) {
fast = fast->next;
}
while (fast != slow) {
fast = fast->next;
slow = slow->next;
}
return fast;
}
};
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
while(fast && fast->next) {
fast = fast->next->next;
slow = slow->next;
if(fast == slow) {
break;
}
}
if(fast && fast->next&&fast == slow) {
ListNode* temp1 = slow;
ListNode* temp2 = head;
while(temp1 != temp2) {
temp1 = temp1->next;
temp2 = temp2->next;
}
return temp1;
}
return nullptr;
}
};