带环问题
基本思路:
快慢指针,慢指针走一步,快指针走两步,如果链表带环,则快指针先进入环内,并且两节点必在环内相遇。
扩展问题:
当快指针一次性走3,4...,n步是否可以。
假设指针内环为两个结点组成,当快指针每次行走3步,两者相差2步。则当慢指针进入环后,快慢指针永远相差2步,无法相遇。
while (slow != fast)
{
if (fast == NULL || fast->next == NULL)
{
return false;
}
slow = slow->next;
fast = fast->next->next;
}
寻找相遇点
数学构造:
L:单链表长度。
X:快指针与相遇点的距离。
R:环的长度。
再相遇之前,快指针和慢指针走的长度分别为:
快指针:L+X+NR(N=1,2,3....);
慢指针:L+X;
由于快指针速度是慢指针的2倍:L+X+NR=2(L+X) ==> L=NR-X;(N=1,2,3....)。
注意:
慢指针进入环后,快指针一定会在一圈之内追上慢指针。而在慢指针进入环之前,快指针会绕圈至少1圈。
while (fast != NULL)
{
slow = slow->next;
if (fast->next == NULL)
{
return NULL;
}
fast = fast->next->next;
if (fast == slow) //L+X+NR=2(L+X)
{
Node* cur = head;
while (cur != slow) //cur==slow时:NR-X=L
{
cur = cur->next;
slow = slow->next;
}
return cur;
}
}
两链表相交问题
当两链表都带环或都不带环才有相交的可能。
此次考虑两者都带环的问题。
设置一个cur,使cur等于M1,使其绕环一周,如果遇到M2则两链表相交。