LC 141, 142 Linked List Cycle I/II Cycles in Linked Lists

The ring in the linked list is a very classic interview question. The important thing is to master the usage of the fast and slow double pointers in the linked list questions. It can not only be used to solve the detection of the ring, but also solve other problems, such as finding the last Nth number in the linked list. , as long as fast is N nodes faster than the slow pointer, and then the two pointers advance together, when fast reaches the end of the linked list, slow points to the Nth node from the bottom (this LC problem was done a few days ago, but I forgot which one ).

LC 141 Linked List Cycle

bool hasCycle(ListNode *head) {
	if(head==NULL||head->next==NULL)
		return false;
    ListNode *f=head,*s=head;
    while(f->next&&f->next->next){
    	f=f->next->next;
    	s=s->next;
		if(f==s)
			return true;
	}
	return false;
}

LC142 Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Note: Do not modify the linked list.

Follow up:
Can you solve it without using extra space?

I have already written the problem-solving idea in the code, and I will copy it directly here. 

L1: distance from head to the entry point of cycle

 L2: distance from the entry point to meeting point
 C: number of points in the cycle
 When the slow pointer enters the cycle, if the cycle is long enough, the fast pointer is L1 points ahead of slow.
 Then the chase within cycle starts. The slow walks L2 steps and the fast walks 2 * L2 steps.
 We have this equation: place of fast + steps that fast walked - n loops == steps that slow walked, that is :
 L1 + 2 * L2 - n * C == L2   ===>    L1 + L2 == n * C
 ******IMPORTANT CONCLUSION******: distance from meeting point to entry point along the forward direction == L1
 If there is only one loop, then L1 + L2 == C, or L1 = C - L2
 Therefore, if we start from the meeting point, let A start from head and B start from meeting point, both walks by one step,

 then A and b shall meet at the entry point of the cycle.

Find the relationship between L1, L2 and C through mathematical methods. When slow and fast meet, let a start from the head and b start from the meeting point. The place where the two pointers meet is where the ring starts. Once you know this conclusion, you can solve this problem very easily. So it feels more like a math problem than a linked list problem.

ListNode *detectCycle(ListNode *head) {
    ListNode *slow = head,*fast = head;
    while(slow != NULL && fast != NULL && fast->next != NULL) {
        slow = slow->next;               //Slow moves by 1 step
        fast = fast->next->next;        //Fast moves by two steps
        //If they meet then there is a loop
        if(slow == fast)
        {
            //To find the starting element where the loop starts
            fast = fast;
            slow = head;
            while(slow != fast)
            {
                //Both move by 1 step
                slow = slow->next;
                fast = fast->next;
            }
            return slow;
        }
    }
    return NULL;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324762706&siteId=291194637