How to operate the fast and slow pointers? This article takes you through three common uses of fast and slow pointers and their practical use in linked lists.

Many students have heard of the termfast and slow pointers, and think it just defines two references (pointers) one after the other? Yes, its mystery is very deep. What are its functions? What topics can it be used for? Below I will take you to understand and apply them one by one

The following is the general content of this section. If you have any questions, please leave a message.

Table of contents

1. Brief description of fast and slow pointers

2. Practical explanation of fast and slow pointers

1. Find the middle node of the linked list

2. The kth node from the last in the linked list

3. Delete all duplicate elements in the sorted linked list

3. A brief summary of question types based on speed and slow pointers


1. Brief description of fast and slow pointers

(1) Fast and slow pointers are just a way of saying it, not a direct definition of two pointers; there is no concept of pointers in Java

(2) The fast and slow pointers define two references. Generally, the slow pointer is defined as slow and the fast pointer is defined as fast.

(3) Common ideas about fast and slow pointers:

1. Generally, the object pointed to by the fast pointer needs to meet certain conditions before the slow pointer can continue to move forward.

2. The fast and slow pointers move together, but each time the fast pointer moves more distance than the slow pointer.

3. The fast pointer moves n steps first, and then the fast and slow pointers move together.

(4) Often used in arrays and linked lists

2. Practical explanation of fast and slow pointers

The following will take you step by step to learn the application of fast and slow pointers in linked lists, how it is used and its applications

1. Find the middle node of the linked list

(1) This is a question on leetcode, the link is attached below

LeetCode official website - a technology growth platform loved by geeks around the world

Don’t panic if you don’t want to click in. I’ll show you the questions below:

(2) Understand the topic

First, this is the problem of singly linked list 

Second, there are two examples given in this question: the first is when the number of nodes is an odd number, and the second is when the number of nodes is an even number. The mathematical formula is: intermediate node = number of nodes/2 ( Specify that the index of the first node is 0)

Third, question requirement: find the middle node and return the middle node

The following explains the solution to this problem

(3) Violent solution (not recommended)

Many students think this way. If you want an intermediate node, you must first know the location of the intermediate node; then traverse the linked list first, write down the number of nodes, and calculate the location of the intermediate node; then traverse the second Repeat it and stop when it reaches the middle position.

Disadvantages: The disadvantages are obvious. The time complexity is too large. If the question requires the time complexity to be O(n), that is, only traverse the linked list once to find the intermediate node, how should students deal with it.

The following introduces the key algorithm ideas of this section: fast and slow pointers
(4) Use fast and slow pointers to solve clever solutions (key points)

Let’s look at the topic again: the following is divided into five steps to explain

Step 1: Define two references pointing to the head node

ListNode slow = head;//慢指针
ListNode fast = head;//快指针

Step 2: How to do it?

We stipulate that each time, the fast pointer takes two steps and the slow pointer takes one step. When the fast pointer stops, the node pointed by the slow pointer is the intermediate node.

Principle analysis:

Step 3: Code Demonstration

ListNode slow = head;
ListNode fast = head;
while(fast != null && fast.next != null) {
       fast = fast.next.next;
       slow = slow.next;
}

Step 4: Judgment conditions for the fast pointer to finish moving

fast != null && fast.next != null

There are two conditions to look at, that is, the number of corresponding nodes is an odd number or an even number. 

Odd number (Condition 1: fast.next != null)

Even number (Condition 2: fast != null)

Step 5: Determine special circumstances

When there is no head node, that is, head==null, then just find a chicken feather and return directly.

 if(head == null) {
     return null;
 }  

Complete code:

public ListNode middleNode(ListNode head) {
        if(head == null) {
              return null;
        }  
        ListNode slow = head;
        ListNode fast = head;

        while(fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }

It can be seen how efficient it is to use fast and slow pointers.

2. The kth node from the last in the linked list

(1) This is a question on Niuke.com, the link is attached below

The kth node from the last in the linked list_NiukeTiba_Niuke.com

Attached is the title below:

(2) Understand the topic

First, we are required to return a certain node from the bottom, and the last label is the first from the bottom;

Second, the questions are limited in time and space, and the knowledge points have double pointer labels.

(3) Violent solution (not recommended)

It's still the same routine. First traverse the linked list and record the total number of nodes; use the total number of nodes - count down a certain node, and then traverse the linked list for the second time to know where to stop.

The time limit of this method may exceed the requirements of the question, and it is not recommended. The solution of the fast and slow pointers is introduced below.

(4) The idea of ​​fast and slow pointers (highly recommended)

Step 1: Define a fast and slow reference, starting with both pointing to the head node.

ListNode slow = head;
ListNode fast = head;

Step 2: To find the K-th node from the bottom, let the fast pointer (fast) take (k-1) steps first.

int count = k-1;//走k-1步
while(count > 0) {
    if(fast.next!=null) {
        fast = fast.next;
       count--;
   }else {
       return null;
   }
}

Step 3: After fast completes k-1 steps, fast and slow walk together. When fast stops, the position of slow is the desired node position.

  while(fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }

Principle and termination conditions:

Special circumstances considerations:

Step 4: Consider special circumstances

When the head node is empty, that is, when there is no node at all, null is returned directly.

 if(head == null) {
    return null;
}

When the value of k is illegal, such as a non-positive number, just return it directly.

if(k<=0) {
    return null;
}

Complete code:

 public ListNode FindKthToTail(ListNode head,int k) {
        if(head == null) {
            return null;
        }
        if(k<=0) {
            return null;
        }
        ListNode slow = head;
        ListNode fast = head;
        int count = k-1;
        while(count > 0) {
           if(fast.next!=null) {
             fast = fast.next;
            count--;
           }else {
            return null;
           }
        }
        while(fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }

        return slow;
    }

3. Delete all duplicate elements in the sorted linked list

(1) This is also a question that closely follows the above question. The following is the connection

LeetCode official website - a technology growth platform loved by geeks around the world

Question appearance:

(2) Understand the topic

First, this is a singly linked list that has been sorted.

Second, to make each value in this singly linked list appear only once, repeated nodes need to be deleted.

(3) Use fast and slow pointers to solve

For this question, we still choose the idea of ​​a fast and slow pointer, that is, the front and rear pointers, which can achieve a time complexity of O(n), that is, it only needs to traverse the linked list once.

Core idea:We let the fast pointer go first. If the value pointed by the fast pointer is the same as the value pointed by the slow pointer, then continue going down until the values ​​pointed to are different. , and then modify the pointing of the slow pointer to complete the deletion of duplicate nodes.

Step 1: Define fast and slow pointers

 ListNode slow = head;
ListNode fast = head.next;

Step 2: Start traversing the linked list

        while(fast != null) {
           while(fast != null && fast.val == slow.val) {
                fast = fast.next;
           }
           if(fast != null) {
                slow.next = fast;
           slow = fast;
           fast = fast.next; 
           }else {
               slow.next = null;
           }
        }
        return head;

Code analysis:

  while(fast != null && fast.val == slow.val) {
        fast = fast.next;
  }

This while loop controls the fast pointer. If the conditions are met, it will continue to go down. There are two situations after exiting this while loop.

The first type:It ends because fast.val != slow.val and the linked list has not been completed

 if(fast != null) {
     slow.next = fast;
     slow = fast;
     fast = fast.next; 
}

In this case, it is necessary to connect the fast and slow pointers to achieve the purpose of deleting duplicate nodes.

Second type:fast == null, the linked list is finished

else {
   slow.next = null;
}

The fast pointer has not met the condition even after it has finished running, indicating that the nodes behind slow are all repeated nodes.

Step Three: Analyze Special Situations

When the node is empty, there is no need to delete it; when there is only one node, there is no duplicate node.

 if(head == null) {
      return null;
 }
 if(head.next == null) {
      return head;
  }

In terms of time efficiency, it directly exceeds 100%.


There is another force-knocking question with a very similar idea to this question. Here is the link. Students can try it by themselves first.

LeetCode official website - a technology growth platform loved by geeks around the world

The question requirement is: delete all key nodes

3. A brief summary of fast and slow pointers

(1) The above are the three common uses of fast and slow pointers. Sometimes, they are also called front and rear pointers.

(2) When the question requires traversing the linked list only once, you should think of the fast and slow pointers. Generally, you only need to define two variables (fast and slow pointers)

(3) When the question requires operations on both ends of the linked list, consider finding the middle node.

(4) When using fast and slow pointers, focus on their linear relationship (how many steps to take respectively) and end conditions


The above is the entire content of this section, students, go and practice!

Guess you like

Origin blog.csdn.net/2301_77053417/article/details/134915793