LeetCode148 Sort List

题目链接:

https://leetcode.com/problems/sort-list/

题目大意:

给一个无序链表排序,要求时间复杂度O(n log n),空间复杂度O(1)。

分析:

最开始看到空间复杂度为常数,第一反应是堆排序。然而并不行,堆排序是基于数组的吧,然后是快排,但是快排掌握的并不好,而且想了一下归并排序如果是用链表的话,其实是可以避免空间复杂度为O(n)的情况的。
里面还涉及一个小算法吧,就是找链表的中点,可以用两个指针,low与high,一个步长为1一个步长为2,当high->next为空或high->next->next为空时,此时low在中点位置。

最近在学数据结构,刚刚学完排序,练下排序的题,顺便加深对链表的影响。主要是有个师兄说我学数据结构就是在背代码,根本不会灵活运用……QAQ好伤感,我自己觉得不是这样的啊,但是既然有人这样说了,我还是多练练LeetCode上的题吧。嗯,这道题确实是道好题,加深了我对链表和归并排序的理解,诶~~~指针指来指去还是有点晕,第一次写MSort函数的时候,传参传的不是指针的引用,链表老是丢结点。关于指针还是要多思考,在脑袋里多指过去指过来几次,慢慢就不晕了。

代码:

class Solution {
public:
    void Merge_Sort(ListNode* &L,ListNode* R){
    ListNode* pHead = (ListNode*)malloc(sizeof(ListNode));
    pHead->next = L;
    ListNode* ptrL = L;
    ListNode* ptrR = R;
    ListNode* pre = pHead;

    while (ptrL!=NULL&& ptrR!=NULL)
    {
        if (ptrL->val <= ptrR->val)
        {
            pre = ptrL;
            ptrL = ptrL->next;
        }
        else
        {
            ListNode* tmp = ptrR->next;
            pre->next = ptrR;
            ptrR->next = ptrL;
            ptrR = tmp;
            pre = pre->next;
        }
    }
    if (ptrR!= NULL)
    {
        pre->next = ptrR;
    }
    L = pHead->next;
}
void MSort(ListNode* &List){
    if (List == NULL || List->next==NULL)
    {
        return;
    }
    ListNode* low=List;
    ListNode* high=List;
    ListNode* pre = NULL;
    ListNode* newList = NULL;
    while (high->next != NULL && high->next->next!=NULL)
    {
        pre = low;
        low = low->next;
        high = high->next->next;
    }
    newList = low->next;
    low->next = NULL;
    MSort(List);
    MSort(newList);
    Merge_Sort(List,newList);

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

你可能感兴趣的:(LeetCode,数据结构,链表,归并排序,148)