Singly linked list OJ title: LeetCode--141. Ring linked list

Friends and guys, we meet again. In this issue, I will explain to you the 141st single-linked list OJ problem in LeetCode. If you have some inspiration after reading it, please leave your trilogy. Best wishes All wishes come true!

Data Structure and Algorithm Column : Data Structure and Algorithm

Personal homepage  : stackY,

C language column : C language: from entry to master

LeetCode--141. Ring linked list: https://leetcode.cn/problems/linked-list-cycle/description/

 1. Topic introduction

Give you the head node head of a linked list, and judge whether there is a ring in the linked list.

If there is a node in the linked list that can be reached again by continuously tracking the next pointer, then there is a cycle in the linked list. In order to represent the ring in the given linked list, the evaluation system internally uses the integer pos to indicate the position where the end of the linked list is connected to the linked list (the index starts from 0). Note: pos is not passed as a parameter. Just to identify the actual situation of the linked list.

Returns true if there is a cycle in the linked list. Otherwise, returns false.

2. Example demonstration 

 

3. Solution ideas 

Here, if you use the most basic method to judge the circular linked list, it will be more troublesome, and there are not many ways, so here I will provide you with a method, which is still the method of fast and slow pointers we are familiar with :

        We can set a fast pointer and a slow pointer. If there is a ring, then the fast pointer and the slow pointer must be able to meet in the ring, because the speed of the fast pointer is always twice that of the slow pointer, so the fast pointer can catch up in the ring Slow pointer, let's use this relatively simple method first, and we can verify it later:

Code demo:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode *head) {
    //设置快慢指针
    struct ListNode* slow = head;
    struct ListNode* fast = head;

    while(fast && fast->next)
    {
        //快指针一次走两步
        fast = fast->next->next;
        //慢指针一次走一步
        slow = slow->next;
        //如果在环中相遇就带环
        if(fast == slow)
        {
            return true;
        }
    }
    //如果整个链表都走完了还是没有相遇则不带环
    return false;
}

This method seems simple, but how to prove it? Let's look down:

4. Expand interview questions

1. Suppose there is a ring, the fast pointer moves one step at a time, and the slow pointer moves two steps at a time, will the fast pointer catch up with the slow pointer?

 The speed of the fast pointer is twice that of the slow pointer, so the fast pointer advances into the ring, and the slow pointer enters the ring behind. We assume that the distance between the fast pointer and the slow pointer is N. After the slow pointer (slow) enters the ring, the fast pointer (fast) starts to chase the slow pointer (slow), the fast pointer takes two steps at a time, and the slow pointer takes one step at a time, then their distance will gradually decrease by 1 with the number of steps they take, which is an arithmetic sequence with a tolerance of -1, then as long as the walking If there are enough steps, the fast pointer will definitely meet the slow pointer.

Therefore, the slow pointer takes one step at a time, and the fast pointer takes two steps at a time, and it will definitely catch up.

2. Assuming there is a loop, if the fast pointer takes any number of steps and the slow pointer takes one step, can the fast pointer catch up with the slow pointer?

Here we assume that the fast pointer moves three steps at a time, and the slow pointer moves one step at a time.

The speed of the fast pointer is 3 times that of the slow pointer, so the fast pointer advances into the ring, and the slow pointer enters the ring later. We assume that the distance between the fast pointer and the slow pointer is N. After the slow pointer (slow) enters the ring, the fast pointer (fast) starts chasing the slow pointer (slow), the fast pointer walks 3 steps at a time, and the slow pointer walks 1 step at a time, then their distance will gradually decrease by 2 with the number of steps they walk, which is an arithmetic sequence with a tolerance of -2. At this time, we need Calculate the distance between them:

The distance of the speed pointer will change to -1 with the increase of the number of steps, which means that the next round of pursuit will start, then the next round of pursuit can be divided into two situations:

1. Assuming that the circumference of the ring is C, the distance between the fast and slow pointers becomes C-1. If C-1 is an odd number at this time, it will never be able to catch up.

2. Assuming that the circumference of the ring is C, then the distance between the fast and slow pointers becomes C-1. If C-1 is an even number at this time, it can catch up.

Summarize:

1. The fast pointer moves one step at a time, and the slow pointer moves two steps at a time. The fast pointer will definitely catch up with the slow pointer.

2. If the fast pointer takes any number of steps and the slow pointer takes one step, the fast pointer may not be able to catch up with the slow pointer.

Friends and guys, the good times are always short-lived. This is the end of our sharing in this issue. Don’t forget to leave your precious trilogy after reading it. Thank you for your support!

Guess you like

Origin blog.csdn.net/Yikefore/article/details/130514068