[32] Rearrange the linked list | Insert and sort the linked list (LeetCode 143 | 147)

Rearranged list

Problem Description

Given a singly linked list L: L0→L1→…→Ln-1→Ln,
rearrange it into: L0→Ln→L1→Ln-1→L2→Ln-2→…

You can't just simply change the internal value of the node, but need to actually exchange the node.

example:
Insert picture description here

Problem-solving ideas

The first thing that comes to mind is the method of separating and combining:
① Divide the linked list into the front part and the back part;
② Reverse the order of the
back part ; ③ Combine the front and back parts.

Schematic:
Insert picture description here
Code:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    int length(ListNode* head){
    
    //求链表的长度
        int n=0;
        while(head){
    
    
            n++;
            head = head->next;
        }
        return n;
    }

    void hebing(ListNode* l1,ListNode* l2){
    
     //合并链表
        while(l1 && l2){
    
    
            ListNode* q = l1->next;
            ListNode* p = l2->next;
            l1->next = l2;
            l1 = q;
            if(!l1) break;
            l2->next = q;
            l2 = p;
        }
    }

    void reorderList(ListNode* head) {
    
    
        if(!head || !head->next) return ;
        int mid = length(head)/2;
        ListNode* cur = head;
        ListNode* hou;
        int i=0;
        while(cur){
    
    //分离链表
            i++;
            if(i<mid){
    
    
                cur = cur->next;
            }else if(i == mid || i == mid+1){
    
    
                ListNode* temp = cur->next;
                hou = cur;
                cur->next = nullptr;
                cur = temp;
            }else{
    
     //将后半段反序
                ListNode* q = cur->next;
                cur->next = hou;
                hou = cur;
                cur = q;
            }
        }
        hebing(head,hou);
    }
};

Time complexity: O(n)
Space complexity: O(1)

Insertion sort on the linked list

Problem Description

Insert sort on the linked list.
Insert picture description here
The animation demonstration of insertion sort is as above. Starting from the first element, the linked list can be considered partially sorted (indicated in black). At each iteration, an element (indicated in red) is removed from the input data and inserted in-situ into the sorted linked list.

Insertion sort algorithm:

Insertion sort is iterative, moving only one element at a time until all elements can form an ordered output list.
In each iteration, insertion sort only removes an element to be sorted from the input data, finds its proper position in the sequence, and inserts it.
Repeat until all input data is inserted.

Problem-solving ideas

Just write according to the algorithm steps of insertion sort:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* insertionSortList(ListNode* head) {
    
    
        if (!head || !head->next)//若链表为空或只有一个结点不需要排序
            return head;
        ListNode* pre_head = new ListNode(0,head);
        ListNode* last = head;
        ListNode* curr = head->next;
        while (curr) {
    
    
            if (last->val <= curr->val) {
    
    //若当前结点的值大于排好序的最后一个值,则直接插在其后
                last = last->next;
            } else {
    
    //否则,从头遍历,找到合适的位置插入
                ListNode *prev = pre_head;
                while (prev->next->val <= curr->val)
                    prev = prev->next;
                last->next = curr->next;
                curr->next = prev->next;
                prev->next = curr;
            }
            curr = last->next;
        }
        return pre_head->next;
    }
};

Time complexity: O(n^2)
Space complexity: O(1)

Experience

It seems that I can write linked list questions at the beginning, but the problem solving is a bit slower.

Guess you like

Origin blog.csdn.net/qq_43424037/article/details/113636291