举例,假设如下环形链表:A->B->C->D->E->F->G->C
判断链表有环
创建快慢指针slow和fast,刚开始都指向链表头,且同时向前走,慢指针每次走1步,快指针每次走2步,如果快慢指针相遇,则说明链表有环。
slow:A->B->C->D->E->F
fast:A->C->E->G->D->F
F为相遇点
list* getMeet(list* start) {
list* meet = nullptr;
for (list* slow = start, fast = start; slow != nullptr, fast != nullptr;) {
if (slow == fast) {
meet = slow;
break;
}
slow++;
fast+=2;
}
return meet;
}
找到有环链表的入环点
首先我们假设相遇时,慢指针走了n步,快指针走了2n步,也就是说环的长度就是n。我们假设环的入口位置为s,慢指针从环的入口开始走了t步,即n=s+t。
由于环的长度就是n,而慢指针从环的入口走了s步,那慢指针继续往前走n-s步会回到环的入口处,而n-s=t,也就是说慢指针继续往前走t步就会回到环的入口处。
所以我们从链表头和相遇位置分别设置一个指针,且每次都是往前走1步,且同时往前走,则从头开始走的指针走t步,相遇位置的指针往前走t步,都会走到环的入口处。
start:A->B->C
meet:F->G->C
这2个指针会同时在环的入口C处相遇
list* getRingStart(list* start, list* meet) {
list* ring_start = nullptr;
while (start != nullptr && meet != nullptr) {
if (start == meet) {
ring_start = start;
break;
}
start++;
meet++;
}
return ring_start;
}