题目

题解

  • 搬移官方题解

/**
 * 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* sortList(ListNode* head) {
        return sortList(head, nullptr);
    }
    ListNode * sortList(ListNode *head, ListNode *tail){
        if(head == nullptr){
            return head;
        }
        if (head->next == tail){
            head->next = nullptr;
            return head;
        }
        ListNode *slow =head, *fast = head;
        while(fast != tail){
            slow = slow->next;
            fast = fast->next;
            if(fast!=tail)fast = fast->next;
        }
        ListNode *mid = slow;
        return merge(sortList(head, mid), sortList(mid,tail));
    }

    ListNode *merge(ListNode *head1, ListNode *head2){
        ListNode *dummy = new ListNode(-1);
        ListNode *temp = dummy, *temp1 = head1, *temp2 = head2;
        while(temp1&&temp2){
            if(temp1->val<temp2->val){
                temp->next = temp1;
                temp1 = temp1 ->next;
            }else{
                temp ->next = temp2;
                temp2 = temp2->next;
            }
            temp = temp->next;
        }
        if(temp1)temp->next = temp1;
        if(temp2)temp->next = temp2;
        return dummy->next;
    }
};
  • 易懂题解

class Solution {
public:
    ListNode* sortList(ListNode* head) { 
        return mergeSort(head);
    }

    /**
     * 对给定的链表进行归并排序
    */
    ListNode* mergeSort(ListNode* head){
        // 如果链表为空或只有一个节点,无需排序直接返回
        if(!head || !head->next){
            return head;    
        }
        // 获取链表的中间节点,分别对左右子链表进行排序
        ListNode* mid = getMid(head);
        ListNode* rightSorted = mergeSort(mid->next);   // 排序右子链表
        if(mid)mid->next = nullptr;                     // 断开两段子链表
        ListNode* leftSorted = mergeSort(head);         // 排序左子链表
        return mergeTwoLists(leftSorted, rightSorted);  // 两个子链表必然有序,合并两个有序的链表
    }

    /**
     * 获取以head为头节点的链表中间节点
     * 如果链表长度为奇数,返回最中间的那个节点
     * 如果链表长度为偶数,返回中间靠左的那个节点
    */
    ListNode* getMid(ListNode* head){
        if(!head)return head;   
        ListNode* slow = head, *fast = head->next;          // 快慢指针,慢指针初始为
        while(fast != nullptr && fast->next != nullptr)     
        {
            fast = fast->next->next;    // 快指针每次移动两个节点
            slow = slow->next;          // 慢指针每次移动一个节点
        }
        return slow;    // 快指针到达链表尾部时,慢指针即指向中间节点
    }

    /**
     * 合并两个有序链表list1和list2
    */
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        ListNode* dummy = new ListNode();   // 伪头节点,用于定位合并链表的头节点
        ListNode* node = dummy;             // 新链表当前的最后一个节点,初始为伪头节点
        // 直到两个链表都遍历完了,合并结束
        while(list1 != nullptr || list2 != nullptr){
            int val1 = list1 == nullptr ? 50001 : list1 -> val;   // 如果链表1已经遍历完,val1取最大值,保证链表2的节点被选择到       
            int val2 = list2 == nullptr ? 50001 : list2 -> val;   // 如果链表2已经遍历完,val2取最大值,保证链表1的节点被选择到 
            if(val1 < val2){
                // 链表1的节点值更小,加入到合并链表,并更新链表1指向的节点
                node -> next = list1;
                list1 = list1 -> next;
            }else{
                // 链表2的节点值更小,加入到合并链表,并更新链表2指向的节点
                node -> next = list2;
                list2 = list2 -> next;
            }
            node = node -> next;    // 更新合并链表当前的最后一个节点指向
        }
        return dummy -> next;       // 伪头节点的下一个节点即为合并链表的头节点
    }
};

作者:画图小匠
链接:https://leetcode.cn/problems/sort-list/solutions/2602280/javapython3cgui-bing-pai-xu-huo-qu-lian-lakrs/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。