leetcode circular linked list Ⅰ and circular linked list Ⅱ

Insert picture description here

We can do this with double pointers. The fast pointer takes two steps at a time and the slow pointer takes one step.
Consider that if there is a ring, then the two pointers will end up on the ring.
Then because the fast pointer takes one step more than the slow pointer every time. So the distance will decrease by one every time, and we will definitely meet.

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    bool hasCycle(ListNode *head) {
    
    
        if(head==NULL) return 0;
        ListNode *slow=head,*fast=head;
        while(fast->next and fast->next->next){
    
    
            fast=fast->next->next;
            slow=slow->next;
            if(fast==slow) return 1;
        }
        return 0;
    }
};


This question is similar to the previous question, except that you want to find the first point of the ring.

There is a mathematical proof for this problem.
We set the length of the path taken by the fast pointer as F, the length of the path taken by the slow pointer as S
, the number of nodes outside the ring as a, and the number of nodes in the ring as b.
Insert picture description here
Because the fast pointer takes two steps each time, F=2S
and because fast and slow will meet on the ring, it is equivalent to saying that fast has walked a few more rings than slow. FS=nb The
first formula is substituted into the second formula to get. S=nb
means that from the beginning of the linked list until the two pointers meet, the length of the slow pointer is the length of several loops!
Then, we only need to use one to go a length from the head of the linked list, and slow to go a length, and it must meet the slow pointer! Because a=(a+nb)%b

And the point at this time is the entrance of the ring!

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    
    ListNode *detectCycle(ListNode *head) {
    
    
         if(head==NULL) return nullptr;
        ListNode *slow=head,*fast=head;
        while(fast->next and fast->next->next){
    
    
            fast=fast->next->next;
            slow=slow->next;
            if(fast==slow){
    
    
                fast=head;
                while(fast!=slow){
    
    
                    slow=slow->next;
                    fast=fast->next;
                }
                return fast;
            }
        }
        return nullptr;
    }
};

Guess you like

Origin blog.csdn.net/qq_43563669/article/details/114235803
Recommended