博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Leetcode:148_Sort List | O(nlogn)链表排序 | Medium
阅读量:4959 次
发布时间:2019-06-12

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

题目:Sort List

Sort a linked list in O(n log n) time using constant space complexity

看题目有两个要求:1)时间复杂度为O(nlogn);2)空间复杂度为常数,即不能增设额外的空间。

满足这样要求的排序算法,我们首先想到快排,合并排序和堆排序。我们来分析下几种排序算法对时间和空间复杂度的要求,堆排序实现上过于繁琐,我们不做考虑。快排的最坏的时间复杂度是O(n^2),平均复杂度为O(nlgn),如果按照题目的严格要求显然快排是不满足的,而且快排的实现引入了递归操作,递归调用的栈空间严格意义上说也是额外空间。另外值得注意的一点是:链表不像数组一样,可以随机访问元素,链表必须顺序访问,所以一般的递归操作很难实现,虽然也可以实现哈,见该文:。对于归并排序,我们知道需要O(n)的空间复杂度,即需要一个临时数组来存放排好序的元素,显然也合理,但那是针对的是数组,对于链表,归并排序的空间复杂度为in-place sort,即不需要额外空间就可以完成。另外,归并排序还有一个比较好的优势是其稳定性。所以,对于本题的解法,我们首选归并排序。

归并排序有多种方式,总的来说有三种,1)递归;2)非递归;3)自然合并;详见本文:。对于链表,采用非递归的方式更为高效,用以下的一幅图来说明非递归的方式:

将两两子列表进行合并组合,达到排序的目的。本题的代码如下,参考上文实现的。

1 ListNode *sortList(ListNode *head)  2 { 3     assert(NULL != head); 4     if (NULL == head) 5         return NULL; 6  7     ListNode *p = head; 8     int len = 0;        //get the length of link 9     while (NULL != p) {10         p = p->next;11         len ++;12     }13 14     ListNode *temp = new ListNode(0);15     temp->next = head;16     17     int interval = 1;   //合并子列表的长度18     for (; interval <= len; interval *= 2) {19         ListNode *pre = temp;20         ListNode *first = temp->next;  //两段子列表的起始位置21         ListNode *second = temp->next;22 23         while (NULL != first || NULL != second) {24             int i = 0;25             while (i < interval && NULL != second) {26                 second = second->next; //将second移到第二段子列表的起始处27                 i ++;28             }29 30             int fvisit = 0, svisit = 0; //访问子列表的的次数
val < second->val) {33 pre->next = first;34 pre = first;35 first = first->next;36 fvisit ++;37 }38 else {39 pre->next = second;40 pre = second;41 second = second->next;42 svisit ++;43 }44 }45 while (fvisit < interval && NULL != first) {46 pre->next = first;47 pre = first;48 first = first->next;49 fvisit ++;50 }51 while (svisit < interval && NULL != second) {52 pre->next = second;53 pre = second;54 second = second->next;55 svisit ++;56 }57 pre->next = second;58 first = second;59 }60 }61 ListNode *retResult = temp->next;62 delete temp;63 temp = NULL;64 return retResult;65 }

 

转载于:https://www.cnblogs.com/bakari/p/4009526.html

你可能感兴趣的文章
iOS7自定义statusbar和navigationbar的若干问题
查看>>
[Locked] Wiggle Sort
查看>>
deque
查看>>
Setting up a Passive FTP Server in Windows Azure VM(ReplyCode: 227, Entering Passive Mode )
查看>>
Python模块调用
查看>>
委托的调用
查看>>
c#中从string数组转换到int数组
查看>>
数据模型(LP32 ILP32 LP64 LLP64 ILP64 )
查看>>
java小技巧
查看>>
POJ 3204 Ikki's Story I - Road Reconstruction
查看>>
【BZOJ】2959: 长跑(lct+缩点)(暂时弃坑)
查看>>
iOS 加载图片选择imageNamed 方法还是 imageWithContentsOfFile?
查看>>
toad for oracle中文显示乱码
查看>>
SQL中Group By的使用
查看>>
错误org/aopalliance/intercept/MethodInterceptor解决方法
查看>>
Pylint在项目中的使用
查看>>
使用nginx做反向代理和负载均衡效果图
查看>>
access remote libvirtd
查看>>
(4) Orchard 开发之 Page 的信息存在哪?
查看>>
ASP.NET中 GridView(网格视图)的使用前台绑定
查看>>