题目链接:142. 环形链表 II - 力扣(LeetCode) (leetcode-cn.com)
链表嘛,无非就那几种方法,玩不出什么花来,最多双指针或者三指针,差不多了,再难点就是快慢指针。
这道题先判断是否存在环,然后再求环的起点。
是否有环很好判断,难想到的就是求环起点,数学推导如下:
设head到环起点为a,环起点到环里快慢指针相遇点为b,相遇点到环起点为c,(环长b+c)则有
a+b+(b+c)*n = 2*(a+b)
化简得:a = (b+c)*(n-1)+c;
特殊值n=1理解的话,就是快指针只转了一圈多就相遇。此时a = c,意思是慢指针再走c距离到环起点,头指针同时走c距离,刚好也到环起点,相遇即是等式。
class Solution { public: ListNode *detectCycle(ListNode *head) { ListNode * slow = head; ListNode * fast = head; while(fast!=nullptr&&fast->next!=nullptr){ fast = fast->next->next; slow = slow->next; if(fast == slow){ ListNode * pre = head; while(pre != slow){ pre = pre->next; slow = slow->next; } return pre ; } } return nullptr; } };
还有,慢指针一定是第一圈还没转完就和快指针相遇了,因为慢指针半圈,快指针转一圈,所以无论快指针在哪,最多慢指针转半圈就相遇了。