Ideas: If you start with two pointers pointing to the head node, one goes fast, one goes slowly, and if there is a ring, eventually passes through a number of steps, the fast hands always go over the slow hands to meet each other.
How to calculate the length of the ring? You can start counting the first time you meet, and stop counting the second time you meet.
How to determine the entry point of the ring? The distance from the collision point P to the connection point = the distance from the head pointer to the connection point, so, starting from the collision point and the head pointer, the point of encounter is the connection point.
When fast meets slow, show must not have gone through the list, and fast has gone N (n>= 1) in the loop. Suppose slow took the S-step, then fast took 2s steps. The number of steps in fast is also equal to S walk plus the Ring of n turns, so
are: 2s = s + Nr. Therefore, S = Nr.
Set the entire list length to L, the entrance according to the meeting point X, the distance from the starting point to the entrance is a. Because the slow pointer does not go through a lap, so: A + x = s, with the result of the first step: A + x =
NR = (n-1) R + R = (n-1) r + l-a; i.e.: a = (n-1) r + l-a-X;
This means: The distance from the head to the entrance is equal to the distance from the point of encounter to the entrance of the (n-1) circle. Therefore, we can set a pointer at the end of the chain, the meeting point, each step each, two pointers must meet, and meet the 1th is the ring entry point.
Determine if there is a ring
bool hascycle (ListNode *head) { *fast (head), *slow (head); while (Fast && fast->next) { = fast->next->next; = Slow->Next; if (Fast = = slow ) return true ; } return false ; }
Calculate the length of the ring
intLooplength (ListNode *head) { if(Hascycle (head) = =false) return 0; ListNode*fast =Head; ListNode*slow =Head; intLength =0; BOOLBegin =false; BOOLagain =false; while(Fast! = NULL && Fast->next! =NULL) {Fast= fast->next->Next; Slow= slow->Next; //stop counting after two laps, pick out loops if(Fast = = Slow && again==true) Break; //start counting after a lap if(Fast = = Slow && again = =false) {begin=true; Again=true; } //Count if(Begin = =true) ++length; } returnlength;}
The entry node of the loop
listnode* findloopentrance (ListNode *head) {ListNode*fast =Head; ListNode* Slow =Head; while(Fast! = NULL && Fast->next! =NULL) {Fast= fast->next->Next; Slow= slow->Next; //If there is a ring, then fast will be more than slow a lap if(Fast = =slow) { Break; } } if(Fast = = NULL | | fast->next = =NULL)returnNULL; Slow=Head; while(Slow! =fast) {Slow= slow->Next; Fast= fast->Next; } returnslow;}
Determine if a linked list has a ring