The problem is described as follows:
Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
Follow up:
Can you solve it without using extra space?
From the perspective of the problem, it is not difficult to make full use of the extra space. However, the question puts forward a requirement on whether the problem can be solved without any additional space.
Through repeated thinking, I think this question is similar to the catch-up problem. You can use a fast traversal pointer and a slow traversal pointer to traverse the linked list. If there is a ring, then this fast pointer will surely catch this slow pointer somewhere in the ring. Despite this idea, how can we further obtain the starting point of a ring after determining whether a ring exists? My personal abilities are limited. I have not done any similar questions before. For the purpose of learning, I checked the materials and got a answer in the leetcode discussion area:
Set a slow pointer slow, a fast pointer fast, slow pointer takes one step at a time, and fast pointer takes two steps at a time. Assume that the distance from head to start of the ring is X, and the length of the ring is Y (that is, the number of steps required to go back from the start point ).
We know that when a ring exists, fast and slow will inevitably encounter a certain place in the ring. Assuming that the distance between start and slow is m, when slow and fast meet at m, slow: x + Ky + M, fast: x + ty + M. Because fast is twice the speed of slow, so:
Ty can be divisible by Y, so x + M + 2ky should also be divisible by Y, that is, (x + M) mod Y = 0. Therefore, it can be inferred that when the two encounter m, and then walk around the ring x step, it will be able to reach the starting point of the ring.
The Code is as follows:
class Solution {public: ListNode *detectCycle(ListNode *head) { if(!head) return NULL; ListNode* slow = head; ListNode* fast = head; do{ if(!fast) return NULL; slow = slow->next; fast = fast->next; if(fast) fast = fast->next; else return NULL; }while( slow != fast ); slow = head; while( slow != fast ){ slow = slow->next; fast = fast->next; } return slow; }};