给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
说明:不允许修改给定的链表。下图有环,返回节点2
解题思路:
利用快慢指针,快指针每次走2步,慢指针每次走1步。如果有环一定相遇的思路来做。设head 到第一个环节点步数为a,第一个环节点到相遇点的步数为b,相遇点再次到第一个环节点的步数为c。
如果有环,一定相遇。那么快指针所走的步数一定是慢指针所走的步数2倍。则有如下关系:
慢指针步数之和:a+b
快指针步数之和:a+b+c+b
2(a+b) = a+b+c+b ,得到 a=c,即head到第一个环节点步数和相遇点再次到第一个环节点的步数相等。
那么从头节点和相遇点同时偏移,交点就是所求的第一个环节点。
代码如下:
struct node {
int value;
node* next;
};
node* detect_cycle(node* head) {
auto fast = head;
auto slow = head;
node* intersect_node = nullptr;
for (; fast != nullptr && fast->next != nullptr;) {
fast = fast->next->next;
slow = slow->next;
if (fast == slow) {
intersect_node = fast;
break;
}
}
if (intersect_node == nullptr) {
return nullptr;
}
for (;;) {
if (head == intersect_node) {
return head;
}
head = head->next;
intersect_node = intersect_node->next;
}
}