博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
leetcode-148 Sort List
阅读量:4121 次
发布时间:2019-05-25

本文共 4199 字,大约阅读时间需要 13 分钟。

递归解法:本来mergesort需要O(n)的空间复杂度,但这里是链表,所以只需要O(1)的空间复杂度

要求时间复杂度为O(nlogn),那么不能用quickSort了(最坏O(n^2)),所以使用mergeSort.

通常写排序算法都是基于数组的,这题要求基于链表。所以需要自己设计函数获得middle元素,从而进行切分。

参考Linked List Cycle II中的“龟兔赛跑”思想:兔子前进两步,龟前进一步,从而可以获得middle元素

注意获取中间节点:需要三个指针:fast slow pre(pre指向slow的上一个位置,可以举两个节点的例子进行带入考虑,如果不适用pre会出错)

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* sortList(ListNode* head) {        if(head == NULL || head->next == NULL) return head;        ListNode *middle = getMiddle(head);        ListNode *head2 = middle->next;        middle->next = NULL;                return merge(sortList(head),sortList(head2));            }        ListNode *getMiddle(ListNode *head){        ListNode *fast = head,*slow = head,*pre = NULL;        while(fast && fast->next){            fast = fast->next->next;            pre = slow;            slow = slow->next;        }        return pre;    }        ListNode *merge(ListNode *first,ListNode *second){        if(first == NULL) return second;        if(second == NULL) return first;        ListNode helper(0);        ListNode *work = &helper;        while(first && second){            if(first->val <= second->val){                work->next = first;                first = first->next;            }else{                work->next = second;                second = second->next;            }            work = work->next;        }                if(first) work->next = first;        if(second) work->next = second;                return helper.next;    }};

参考:http://www.cnblogs.com/ganganloveu/p/3763707.html

非递归解法:

Nice problem. I use a non-recurisve way to write merge sort. For example, the size of ListNode is 8,

Round #1 block_size = 1

(a1, a2), (a3, a4), (a5, a6), (a7, a8)

Compare a1 with a2, a3 with a4 ...

Round #2 block_size = 2

(a1, a2, a3, a4), (a5, a6, a7, a8)

merge two sorted arrays (a1, a2) and (a3, a4), then merge tow sorted arrays(a5, a6) and (a7, a8)

Round #3 block_size = 4

(a1, a2, a3, a4, a5, a6, a7, a8)

merge two sorted arrays (a1, a2, a3, a4), and (a5, a6, a7, a8)

No need for round #4 cause block_size = 8 >= n = 8

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution{public:    ListNode *sortList(ListNode *head){        if(head == NULL || head->next == NULL) return head;        int n = countList(head),iter = 0,blockSize = 1,a = 0,b = 0;        ListNode *A,*B,*it,*last,*tmp;        ListNode helper(0); //排序可能会打乱第一个结点(head)的顺序,所以需要一个辅助节点        last = &helper;        last->next = head;                while(blockSize < n){            iter = 0;            it = helper.next;            last = &helper;   //last为排序时候的工作节点                        while(iter < n){                a = min(n - iter,blockSize);                b = min(n - iter - a,blockSize);                A = it;  //待排序的第一个块的第一个结点                                if(b != 0){                    for(int i = 0; i < a - 1; i++) it = it->next;                    B = it->next;                    it->next = NULL;                    it = B;  //待排序的第二个块(和A相邻的块)的第一个结点                                        for(int j = 0; j < b - 1; j++) it = it->next;                    tmp = it->next;                    it->next = NULL;                    it = tmp;                }                                while(A || B){                    if(B == NULL || ( A != NULL && A->val <= B->val)){                        last->next = A;                        A = A->next;                    }else{                        last->next = B;                        B = B->next;                    }                    last = last->next;                }                last->next = NULL;                iter += a + b;   //iter为已经排序的节点个数            }            blockSize <<= 1;        }        return helper.next;    }        int countList(ListNode *head){        int n = 0;        while(head){            n++;            head = head->next;        }        return n;    }};

参考:https://leetcode.com/discuss/10264/my-o-n-log-n-time-o-1-space-solution

你可能感兴趣的文章
对话周鸿袆:从程序员创业谈起
查看>>
web.py 0.3 新手指南 - 如何用Gmail发送邮件
查看>>
web.py 0.3 新手指南 - RESTful doctesting using app.request
查看>>
web.py 0.3 新手指南 - 使用db.query进行高级数据库查询
查看>>
web.py 0.3 新手指南 - 多数据库使用
查看>>
一步步开发 Spring MVC 应用
查看>>
python: extend (扩展) 与 append (追加) 的差别
查看>>
「译」在 python 中,如果 x 是 list,为什么 x += "ha" 可以运行,而 x = x + "ha" 却抛出异常呢?...
查看>>
浅谈JavaScript的语言特性
查看>>
LeetCode第39题思悟——组合总和(combination-sum)
查看>>
LeetCode第43题思悟——字符串相乘(multiply-strings)
查看>>
LeetCode第44题思悟——通配符匹配(wildcard-matching)
查看>>
LeetCode第45题思悟——跳跃游戏(jump-game-ii)
查看>>
LeetCode第46题思悟——全排列(permutations)
查看>>
LeetCode第47题思悟—— 全排列 II(permutations-ii)
查看>>
LeetCode第48题思悟——旋转图像(rotate-image)
查看>>
驱动力3.0,动力全开~
查看>>
记CSDN访问量10万+
查看>>
Linux下Oracle数据库账户被锁:the account is locked问题的解决
查看>>
记CSDN访问20万+
查看>>