想法一
由环形链表题中,沿用快慢指针思想,再结合以下结论
https://blog.csdn.net/2301_79188764/article/details/134299433
struct ListNode *detectCycle(struct ListNode *head)
{
struct ListNode *slow = head, *fast = head;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
struct ListNode *meet = slow;
while (head != meet)
{
head = head->next;
meet = meet->next;
}
return meet;
}
}
return NULL;
}
结论分析和推导
好像分析的很对,是吧?但是,很遗憾的告诉你,这个推论是错的!
这样,推论才是对的,前面只是特殊情况,刚好符合结论而已
想法二
将链表的环切断,转换为链表相交问题
https://blog.csdn.net/2301_79188764/article/details/134298439
思路比较简单,没有用数学结论,但是代码比较长
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{
struct ListNode *tail1 = headA, *tail2 = headB;
int len1 = 1, len2 = 1;
while (tail1->next)
{
tail1 = tail1->next;
len1++;
}
while (tail2->next)
{
tail2 = tail2->next;
len2++;
}
if (tail1 != tail2)
{
return NULL;
}
int gap = abs(len1 - len2);
struct ListNode *longlist = headA, *shortlist = headB;
if (len1 < len2)
{
longlist = headB;
shortlist = headA;
}
while (gap--)
{
longlist = longlist->next;
}
while (longlist != shortlist)
{
longlist = longlist->next;
shortlist = shortlist->next;
}
return longlist;
}
struct ListNode *detectCycle(struct ListNode *head)
{
struct ListNode *slow = head, *fast = head;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
struct ListNode *meetNext = slow->next;
slow->next = NULL;
return getIntersectionNode(head, meetNext);
}
}
return NULL;
}