Common techniques for brushing questions in linked lists - fast and slow pointers

Powerful, as immovable as a mountain, the real strength that will not lose to oneself. 

Past review:

Data Structure - Singly Linked List

Single-link table buckle brush question

Article directory

Classic example: the intermediate node of the linked list

Topic analysis and introduction of double-pointer ideas 

Dual Pointer Diagram

leetcode core code

Judging the circular linked list - the extension of the fast and slow pointers is a catch-up problem

topic analysis, graphic

leetcode core code


  Hello everyone, I am Ji Ning.

  Most of the interviews and written tests in the part of the data structure linked list are in the part of the single linked list, and most of the questions are head nodes without sentinel bits, and the questions are usually relatively difficult. This article will introduce to you a common technique for solving problems here in a singly linked list-fast and slow pointers.

  The so-called fast and slow pointers mean that there are two pointers to maintain the singly linked list, usually defined as slow and fast, and these two pointers traverse the linked list at different speeds.

Classic example: the intermediate node of the linked list

  Given the head node of the singly linked list  head , please find and return the middle node of the linked list. If there are two intermediate nodes, return the second intermediate node.

Topic analysis and introduction of double-pointer ideas 

  In this question, if you are looking for the middle element of the array, it may be relatively simple, directly calculate the size of the array, and then stipulate that only half of the content can be traversed. But in the linked list, you know nothing except the content of the current node and the address of the next node, so you can't control where the pointer goes.

  There is a particularly ingenious method, which is to define two pointers, one pointer slow takes one step backward at a time, slow = slow->next; one pointer takes two steps back at a time, fast = fast -> next ->next, In this way, when the pointer fast or fast->next becomes a NULL pointer, the slow pointer just goes to the middle of the linked list, thus finding the middle node of the linked list.

Dual Pointer Diagram

When the linked list length is odd

When the linked list length is even 

 

leetcode core code

struct ListNode* middleNode(struct ListNode* head){
    struct ListNode*slow,*fast;
    slow=head;
    fast=head;
    while(fast!=NULL&&fast->next!=NULL)
    {
        fast=fast->next->next;
        slow=slow->next;
    }
    return slow;
}

  One thing to note in the code is that because the fast pointer goes 'two steps' at a time, the termination condition of the loop is that fast or fast->next is empty, and finally returns the slow pointer.

Judging the circular linked list - the extension of the fast and slow pointers is a catch-up problem

Question: Given the head node of a linked list  head , determine whether there is a ring in the linked list.

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

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

topic analysis, graphic

  As shown in the figure: the linked list above enters the ring at d3, the pointer field of d6 points to d3, and then the linked list will circulate in the ring of d3——d4——d5——d6——d3.

  First of all, this question does not give the position to enter the ring, so there are many possibilities to enter the ring, which excludes the idea of ​​traversing the linked list. This question can also use the method of fast and slow pointers. The fast pointer and the slow pointer start to walk backward from the head pointer at the same time. The fast pointer takes two steps at a time, and the slow pointer takes one step at a time to see if the two pointers can meet.

  If the linked watch has a ring, the fast pointer and the slow pointer must meet, otherwise they will not meet. This chasing principle is similar to going to the playground to run laps with your girlfriend. You start at the same time. As long as you run faster than her and you don't stop until you meet, you will be able to achieve laps. 

  Therefore, as long as the pointer fast and the pointer slow go backward and find that they point to the same (fast==slow), it means that the linked list has a loop (a loop). If fast or fast->next is empty, it means that the traversal of the linked list has ended, and the linked list has no rings. 

leetcode core code

bool hasCycle(struct ListNode *head) {
    struct ListNode *slow=head;
    struct ListNode *fast=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(fast==slow)
            return true;
    }
    return false;
}

  This is the common technique for solving questions in the single-linked list part brought to you by the blogger - the speed pointer, thank you for watching.

おすすめ

転載: blog.csdn.net/zyb___/article/details/132024454