Leetcode: 剑指 Offer II 077. 链表排序

给定链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。

进阶:你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?

题目分析:

1、由于时间复杂度的要求,选择归并排序

2、需要把链表分为前后两个部分  分别进行归并排序后   合并链表 

3、需要实现的函数:split链表, Merge两个链表

----  split链表部分:采用slow fast指针的方式找到中间节点 并且返回

-----Merge链表的部分:比较两部分链表节点的大小  cur指向val小的节点  并且指针后移  最后返回合并后的链表头结点

具体代码如下:

/**
 * 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 {

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

    ListNode* Merge(ListNode* head1, ListNode* head2) {
        ListNode* dummyhead = new ListNode(-1);
        ListNode* cur = dummyhead;
        while(head1 != nullptr && head2 != nullptr) {
            if(head1->val < head2-> val) {
                cur->next = head1;
                head1 = head1->next;
            } else {
                cur->next = head2;
                head2 = head2 -> next;
            }
            cur = cur -> next;
        }
        if(head1 != nullptr) cur -> next = head1;
        else cur -> next = head2;

        ListNode* res = dummyhead -> next;
        delete dummyhead;
        dummyhead = nullptr;
        return res;
    }

public:
    ListNode* sortList(ListNode* head) {
        if(head == nullptr || head -> next == nullptr) return head;
        ListNode* head1 = head;
        ListNode* head2 = find_mid(head);
        head1 = sortList(head1);
        head2 = sortList(head2);
        return Merge(head1, head2);
    }
};



猜你喜欢

转载自blog.csdn.net/qq_44189622/article/details/129404613