Sword Pointer Offer II 026. Rearranging the Linked List

Please add a picture description

Ideas:
(1) Find the center point of the linked list. If the number of nodes in the linked list is odd, then ensure that there is one more node in the front than the back.
(2) Invert the nodes in the latter part.
(3) Insert the reversed node into the node in the previous part.

(1) Find the center of the linked list
    To find the center of the linked list, the fast and slow pointers are mainly used. When the fast pointer starts at twice the speed and the pointer points to the end, the slow pointer just points to the center. The difficulty is mainly to consider the stopping condition. Because the fast pointer may not be able to move 2 steps for the last time, it is necessary to judge whether it is empty after moving one step, and continue to move if it is not empty. After moving, it may be empty or not empty, so the condition of the loop is fast The pointer is empty, or let the fast pointer be empty in the next step, so as to ensure that the loop condition meets the requirements. Finally returns the slow pointer.

ListNode* findmid(ListNode* head)
{
    
    
    ListNode* fast = head;
    ListNode* slow = head;
    while (fast->next != nullptr&&fast!=nullptr)
    {
    
    
        slow = slow->next;
        fast = fast->next;
        if (fast->next != nullptr)
        fast = fast->next;
    }
    return slow;
}

(2) Reversing the linked list
Here, the recursive method is used to reverse directly.

ListNode* reverseList(ListNode* head) {
    
    
    if (!head || !head->next) {
    
    
        return head;
    }
    ListNode* newHead = reverseList(head->next);
    head->next->next = head;
    head->next = nullptr;
    return newHead;
}

(3) Insert linked list

    Inserting the linked list is the most complicated step, because when you modify the next of a node, all subsequent elements will be overwritten, so the most important thing is to save the following elements in advance and cycle the process during the movement. Two pointers are added here, one is temp, its function is to save the next element in the main chain, and the other is pre, its function is to save the next element in the side chain. Generally speaking, the main chain must point to the sub-chain (head->next = newHead). At this time, there must be a variable to save the last node of the main chain (ListNode* temp = head->next). After each end To point the main chain to the latter (head = temp). Similarly, every time the main chain is activated, the sub-chain must also point to the main chain once (pre->next = head), and the sub-chain must also be moved (pre = newHead, newHead = newHead->next).

   ListNode* cut(ListNode* head, ListNode* newHead)
    {
    
    
        ListNode* pre = new ListNode(0);
        pre->next = head;
        while (head != nullptr && newHead != nullptr)
        {
    
    
            ListNode* temp = head->next;
            pre->next = head;
            head->next = newHead;
            pre = newHead;
            
            head = temp;
            newHead = newHead->next;
        }
        if (head != nullptr)
        {
    
    
            pre->next = head;
        }
        return head;
    }


(4) There is a chain-breaking operation in the middle of the main function .

void reorderList(ListNode* head) {
    
    
    ListNode* mid = findmid(head);
    ListNode* next = mid->next;
    mid->next = nullptr;
    ListNode* newHead = reverseList(next);
    ListNode* newnewHead = cut(head, newHead);
}

Guess you like

Origin blog.csdn.net/daweq/article/details/130380952