[LeetCode] Data structure problem solution (8) [entry node in the linked list]

Belonging column: Playing with data structure question types
Blogger's homepage: Chuyang785
Code hosting: chuyang785
Thank you for your support, your likes and attention are the greatest support for me! ! !
Bloggers will also work harder to create better blog posts! !
Follow me, follow me, follow me, say important things three times! ! ! ! ! ! ! !

1. Source of topic

entry node in linked list

2. Topic description

Given a linked list, return the first node where the linked list starts entering the ring. Starting from the head node of the linked list and following the next pointer into the ring, the first node is the entry node of the ring. Returns null if the linked list is acyclic.

To represent a cycle in a given list, we use the integer pos to denote the position in the list where the tail of the list joins (indexes start at 0). If pos is -1, there are no cycles in the list. Note that pos is only used to identify the ring and will not be passed as a parameter to the function.

Description: Modification of the given linked list is not allowed.

insert image description here

3. Problem-solving ideas

  • Here to judge the nodes of the ring, we use the mathematical pursuit problem, that is, in a circle, two particle points start at the same time, but at different speeds, and ask when they can catch up.
  • We first explain the idea of ​​the topic, and then talk about the principle.
  1. The first is to prove that they exist rings. Our problem-solving idea is to use the fast and slow pointers, the slow pointer takes one step, and the fast pointer takes two steps. Once they are equal, it means that they have a ring.
  2. Then find the interface of the ring. At this time, we traverse head and low at the same time, and when head==low, we find the interface of the ring.

Principle:
At this time, some people will ask why you choose low to take one step and fast to take two steps. Can it be other ratios?
We first prove that the idea we gave is correct.
insert image description here

We first abstract our linked list as shown in the figure.
insert image description here
insert image description here
Once they meet, that is to say, the distance traveled by fast is twice that of low.
So we have a mathematical expression:2*(L+x) = L+nS+x. Note: The reason why nS is used here is because S may be very small, and fast has already walked many circles when low starts to enter the circle. After simplification, we get:L=nS-x.
insert image description here
So we can traverse from head and low at the same time, knowing that the same is the intersection point.

Now let's talk about why not use other ratios but 1:2 ratio.
If our ratio becomes 1:3, let's discuss it.
Get the picture just now:
insert image description here
After the ratio here becomes 1:3, the difference between the distance between low and fast per second becomes 2.
First second: distance between two points: x-2
Second second: distance between two points: x-4
...
nth second: distance between two points: x-2^n
If our x is an even number then they will meet.
But if their x is an odd number, they will not necessarily meet.
reason:
insert image description here

If our y is an even number, then they will meet, because the difference between them every second is 2, and they will always meet.
But if y is odd then they will never meet again. Because we know that the difference between them every second is 2, and our y is an odd number, which means that when they are about to meet, fast will always be at the previous unit of low, that is, they will return to The structure in the picture above will always return to the picture above, and they will never meet again.
There are similar situations in other ratios, so we choose the speed of 1 to 2 to judge.

4. Code display

struct ListNode *detectCycle(struct ListNode *head) 
{
    //先判断有没有环
    //使用快慢指针
    struct ListNode *fast,*low;
    fast=low=head;
    while(fast && fast->next)
    {
        low=low->next;
        fast=fast->next->next;

        if(fast == low)
        {
            struct ListNode* meet=low;
                //在判断入环的第一个接节点
            while(meet != head)
            {
                meet=meet->next;
                head=head->next;
            }
            return meet;
        }
    }
    return NULL;

}

Guess you like

Origin blog.csdn.net/qq_74276498/article/details/130622191