【LeetCode】234 speed pointer | reverse linked list | restore linked list

 

Table of contents

1. Introduction to the topic

2. Problem-solving ideas

2.1. Brute force cracking method

2.2. Fast and slow pointer inversion linked list


 

1. Introduction to the topic

Original question link: 234. Palindrome Linked List - LeetCode

Example 1:

Input:head = [1,2,2,1]
Output:true 

Example 2:

Input:head = [1,2]
Output:false 

hint: 

  • The number of nodes in the linked list is within the range [1, 10^5]
  • 0 <= Node.val <= 9

Advanced:Can you solve this problem using O(n) time complexity and O(1) space complexity?

2. Problem-solving ideas

To determine a palindrome is to determine whether it is symmetrical. Some friends are very familiar with the palindrome judgment of arrays, but they may not know how to judge the palindrome of linked lists. In fact, they are all the same. There is a very simple way to convert the linked list into an array, and then just judge whether the array is a palindrome. This method is collectively called the brute force cracking method , simple and crude. Now let's take a look at the brute force cracking method for this question.

2.1. Brute force cracking method

There are two steps in total:

  1. Copy linked list values ​​into array list.
  2. Use the double pointer method to determine whether it is a palindrome.

First, define an integer array with a size of 100001 according to the maximum size required by the question, then take out the value of each node in the linked list and put it into the array through loop traversal, and finally judge it through two pointers, one from the left and the other from the right. Whether they are equal or not, false is returned whenever an inequality is encountered, otherwise true is returned when the loop ends.

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool isPalindrome(struct ListNode* head){
    int arr[100001] = {0},num = 0;
    while(head)
    {
        arr[num] = head->val;
        head = head->next;
        num++;
    }
    int i= 0;
    int j =0;
    for(i = 0,j = num-1; i<j; i++,j--)
    {
        if(arr[i]!=arr[j])
        {
            return false;
        }
    }
    return true;
}

Time complexity:O(n), where n refers to the number of elements in the linked list.

  • Step one: Traverse the linked list and copy the values ​​into the array, O(n).
  • Step 2: Determine whether the double pointer is a palindrome. O(n/2) judgments are performed, that is, O(n).
  • Total time complexity: O(2n)=O(n).

Space complexity:O(n), where n refers to the number of elements in the linked list, we use an array list to store The element value of the linked list.

Advanced:Can you solve this problem using O(n) time complexity and O(1) space complexity?

The following will show you how to advance this question. Usefast and slow pointers to reverse the linked list to implement an algorithm with a space complexity of O(1) .

2.2. Fast and slow pointer inversion linked list

The entire process can be divided into the following five steps:

  1. Find the tail node of the first half of the linked list.
  2. Reverse the second half of the linked list.
  3. Determine whether it is a palindrome.
  4. Restore the linked list.
  5. Return results.

For the first step to find the tail node of the first half of the linked list, we can calculate the number of nodes in the linked list and then find the tail node of the first half, or we can use the fast and slow pointers Find the end node of the first half in one traversal.

The slow pointer takes one step at a time, the fast pointer takes two steps at a time,The fast and slow pointers start at the same time. When the fast pointer moves to the end of the linked list, the slow pointer goes exactly to the middle of the linked list. The linked list is divided into two parts through slow pointers.

At this time, slow is the tail node of the first half, and the next node of slow is the head node of the second half. So let fast return to the next node of slow, reverse all the nodes in the second half, and then empty the last node of slow, the first half.

Then slow will start again from the head, fast will start from the last node, and approach the middle node respectively and judge. As long as they are equal, they will always move closer to the middle. If they encounter differences, they will directly return false. Otherwise, they will return true when the loop exits. .

Finally, restore the reversed linked list back.​ 

 Code:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool isPalindrome(struct ListNode* head){
    if(head == NULL || head->next == NULL)
    {
        return true;
    }
    struct ListNode* n1 = head;
    struct ListNode* n2 = head;
    //快慢指针遍历
    while(n2->next != NULL && n2->next->next != NULL)
    {
        n1 = n1->next;          //慢指针
        n2 = n2->next->next;    //快指针 
    }
    n2 = n1->next;   //右边第一个
    n1->next = NULL;
    struct ListNode* n3;
    //反转右半边链表
    while(n2 != NULL)
    {
        n3 = n2->next;  //n3存放n2的next
        n2->next = n1;
        n1 = n2;
        n2 = n3;
    }
    //当循环结束时n1所指向的位置就是链表最后一个结点,
    n2 = n3 = n1;  //将n2和n3指回最后一个节点
    n1 = head;     //n1回到头结点
    bool flag = true;
    //判断是否是回文
    while(n1 != NULL && n2 != NULL)
    {
        if(n1->val != n2->val)
        {
            flag = false;
            break;
        }
        n1 = n1->next;
        n2 = n2->next;
    }
    //还原链表
    n2 = n3->next;    //n3此时指向最后一个结点,因为反转了链表,n3的next就是上一个结点
    n3->next = NULL;
    while(n2!=NULL)
    {
        n1 = n2->next;
        n2->next = n3;
        n3 = n2;
        n2 = n1;
    }

    return flag;
}

Time complexity:O(n), where n refers to the size of the linked list.

Space complexity:O(1). We will only modify the pointing of the node in the original linked list, and the stack frame on the stack will not exceed O(1).

 More【LeetCode Question Brush】Recommendations:

【LeetCode】86. Separated Linked List-CSDN Blogicon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/133942678?spm=1001.2014.3001.5501< /span>https://blog .csdn.net/zzzzzhxxx/article/details/133578735[LeetCode] LCR170 Use the idea of ​​​​merge sort to solve the reverse order problem (detailed illustration)_Hacynn's blog-CSDN bloghttps://blog.csdn.net/zzzzzhxxx/article/details /133827375[LeetCode] 297. Serialization and Deserialization of Binary Trees-CSDN Blogicon-default.png?t=N7T8icon-default.png?t=N7T8

 

If you think the author's writing is good, please give the blogger a big like and support. Your support is my biggest motivation for updating!

If you think the author's writing is good, please give the blogger a big like and support. Your support is my biggest motivation for updating!

If you think the author's writing is good, please give the blogger a big like and support. Your support is my biggest motivation for updating!

 

Guess you like

Origin blog.csdn.net/zzzzzhxxx/article/details/133958602
Recommended