[LeetCode OJ] Sort List 解题报告

题目地址:https://oj.leetcode.com/problems/sort-list/

题意:简单的说就是不再开辟新的内存,用O(NlogN)的排序将现有链表排序

解题思路:O(NlogN)的复杂度,我想到的是堆排或者归并,但是这道题节点的构造不符合堆排。链表的归并排序我是第一次写,凡是和指针挂钩的都要注意边界处理。

要点:归并排序的要点就是找到中点,然后二分,再合并。

1.拆分:对于链表,找中点就相当于将链表截断为两个长度差小于2的新链表,这里的操作是findMid()函数,注意边界处理。

2.合并:归并排序再合并时将两个有序子链表合并成一个,用链表实现归并排序的好处就是不用像数组实现时开辟新内存空间,这里的操作是merge()函数,要注意链表合并时的极端情况,列如:子列表1的元素全部大于子列表2里的元素。

总结:复习了归并排序,学习了链表的排序。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
ListNode* mergeSort(ListNode *List){
    if(!List||!(List->next)) return List;
    ListNode *mid = NULL;
    mid = findMid(List);
    ListNode* List1 = mergeSort(List);
    ListNode* List2 = mergeSort(mid);
    return merge(List1,List2);
}

ListNode *findMid(ListNode *head){
    ListNode *ptr1=head;
    ListNode *ptr2=head->next;
    while(ptr2&&ptr2->next){
        ptr1 = ptr1->next;
        ptr2 = ptr2->next;
        if(ptr2->next == NULL) //小心越界
            break;
        ptr2 = ptr2->next;
    }
     ListNode *pre = ptr1;
     ptr1 = ptr1->next;
     pre->next =NULL; //截断两个链表
     return ptr1;
}

ListNode* merge(ListNode *List1, ListNode *List2){
    ListNode *head = NULL;
    ListNode  *ptr = NULL;
    ListNode *head1 = List1;
    ListNode *head2 = List2;
    while(head1 != NULL && head2 != NULL){
        if(head1->val < head2->val){
            if(head == NULL){
                ptr = head = head1;
            }
            else{
                ptr->next =head1;
                ptr = ptr->next;
            }
            head1 = head1->next;
        }
        else{
            if(head == NULL){
                ptr = head = head2;
            }
            else{
                ptr->next =head2;
                ptr = ptr->next;
            }
            head2 = head2->next;
        }
    }

    while(head1 != NULL){
        if(head == NULL)
            ptr = head = head1;
        else{
            ptr->next =head1;
            ptr = ptr->next;
        }
        head1 = head1->next;
    }

    while(head2 != NULL){
        if(head == NULL)
            ptr = head = head2;
        else{
            ptr->next =head2;
            ptr = ptr->next;
        }
        head2 = head2->next;
    }
    ptr->next = NULL;
    return head;
}

ListNode *sortList(ListNode *head) {
    return mergeSort(head);
}

};

点赞