leetcode sort List
Sort a linked list in O(n log n) time using constant space complexity. /**
* 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)
return NULL;
int k=;
ListNode *p=head;
while(p)
{
k++;
p=p->next;
}
if(k==)
return head;
int l=k/; //计算结点个数,将链表分开。
p=head;
ListNode *q=head,*t=NULL;
for(int i=;i<l && q ;i++)
{
if(i==l-)
t=q;
q=q->next;
}
if(t)
t->next=NULL;//将链表分开。
p=sortList(p);//分别对两段排序
q=sortList(q);
ListNode *hd=NULL,*pp=NULL;
while(p&&q)//合并
{
if(p->val<=q->val)
{
if(!hd)
pp=hd=p;
else
{
pp->next=p;
pp=p;
}
p=p->next;
}
else
{
if(!hd)
hd=pp=q;
else
{
pp->next=q;
pp=q;
}
q=q->next;
}
}
if(p)
pp->next=p;
if(q)
pp->next=q;
return hd;
}
};
分析如下:
挺有意思的一道题目。表面上看,能够有O(n lgn)时间复杂度的算法为,快速排序,堆排序,归并排序,三者的空间复杂度分别为O(1), O(N),O(N)
所以一开始,我想着用快速排序的方法来解决,但是发现代码很难写出来。于是网上看了一下提示,发现其实方法选错了。应该使用的方法是归并排序。
通常而言,也就是针对数组而言,归并排序的空间复杂度为O(N), 你需要开出O(N)的额外空间来容纳数组,来表示归并后的顺序。但是,对于链表而言,你可以省下这部分空间的开销,你只需要改变节点的next指针的指向,就可以表示新的归并后的顺序了,所以空间复杂度陡然降到了O(1)
小结:
(1)挺有意思的一道题目,需要在新的条件和环境下去思考旧的结论是否依然成立。
(2)快速排序和归并排序的时间复杂度都是O(N lgN),但是CLRS说了,实践证明快速排序的速度比归并排序的速度更快,为什么呢?另外其实这个结论是有限制范围的,当对数组进行排序的时候,这个结论适用。为什么对于链表,却是归并排序的速度优于快速排序呢?这里看到的一段对比说得挺好,直接抄过来。
One of the main sources of efficiency in quicksort is locality of reference, where the computer hardware is optimized so that accessing memory locations that are near one another tends to be faster than accessing memory locations scattered throughout memory. The partitioning step in quicksort typically has excellent locality, since it accesses consecutive array elements near the front and the back. As a result, quicksort tends to perform much better than other sorting algorithms like heapsort even though it often does roughly the same number of comparisons and swaps, since in the case of heapsort the accesses are more scattered.
Additionally, quicksort is typically much faster than other sorting algorithms because it operates in-place, without needing to create any auxiliary arrays to hold temporary values. Compared to something like merge sort, this can be a huge advantage because the time required to allocate and deallocate the auxiliary arrays can be noticeable. Operating in-place also improves quicksort's locality.
When working with linked lists, neither of these advantages necessarily applies. Because linked list cells are often scattered throughout memory, there is no locality bonus to accessing adjacent linked list cells. Consequently, one of quicksort's huge performance advantages is eaten up. Similarly, the benefits of working in-place no longer apply, since merge sort's linked list algorithm doesn't need any extra auxiliary storage space.
That said, quicksort is still very fast on linked lists. Merge sort just tends to be faster because it more evenly splits the lists in half and does less work per iteration to do a merge than to do the partitioning step.
归纳一下,就是说,如果待排序的元素存储在数组中,那么快速排序相对归并排序就有两个原因更快。一是,可以很快地进行元素的读取(相对于链表,数组的元素是顺序摆放的,而链表的元素是随机摆放的),数组的partion这步就比链表的partion这步快。二是,归并排序在merge阶段需要辅助数组,需要申请O(N)的空间,申请空间也是需要时间的。而快排不需要额外申请空间。如果待排序的元素存储在链表中,快排的优点就变成了缺点。归并排序于是就速度更优了。
leetcode sort List的更多相关文章
- LeetCode—-Sort List
LeetCode--Sort List Question Sort a linked list in O(n log n) time using constant space complexity. ...
- [LeetCode] Sort Characters By Frequency 根据字符出现频率排序
Given a string, sort it in decreasing order based on the frequency of characters. Example 1: Input: ...
- [LeetCode] Sort List 链表排序
Sort a linked list in O(n log n) time using constant space complexity. 常见排序方法有很多,插入排序,选择排序,堆排序,快速排序, ...
- [LeetCode] Sort Colors 颜色排序
Given an array with n objects colored red, white or blue, sort them so that objects of the same colo ...
- [leetcode]Sort Colors @ Python
原题地址:https://oj.leetcode.com/problems/sort-colors/ 题意: Given an array with n objects colored red, wh ...
- LeetCode: Sort List 解题报告
Sort List Sort a linked list in O(n log n) time using constant space complexity. 使用Merge Sort, 空间复杂度 ...
- LeetCode Sort List 链表排序(规定 O(nlogn) )
Status: AcceptedRuntime: 66 ms 题意:根据给出的单链表,用O(nlogn)的时间复杂度来排序.由时间复杂度想到快排.归并这两种排序.本次用的是归并排序.递归将链表的规模不 ...
- [LeetCode] Sort Transformed Array 变换数组排序
Given a sorted array of integers nums and integer values a, b and c. Apply a function of the form f( ...
- Leetcode: Sort Transformed Array
Given a sorted array of integers nums and integer values a, b and c. Apply a function of the form f( ...
随机推荐
- Python3利用BeautifulSoup4抓取站点小说全文的代码
再写一个用BeautifulSoup抓站的工具,体会BeautifulSoup的强大. 根据小说索引页获取小说全部章节内容并在本地整合为小说全文.不过不是智能的,不同的站点对代码需要做相应的修改. # ...
- I/O复用
1.I/O模型 一个输入操作通常包括两个不同阶段:等待数据准备好:从内核到进程拷贝数据. 阻塞I/O模型 非阻塞I/O模型 I/O复用模型:内核发现进程指定的一个或多个I/O条件就绪,它就通知进程,由 ...
- 初试Nodejs——使用keystonejs创建博客网站1(安装keystonejs)
我正在阿里云上创建一个简单的个人博客网站,刚好正在尝试NodeJs,决定找一款基于NodeJs的CMS来完成这个工作,最后找到了KeyStoneJS. KeyStoneJS是基于Express和Mon ...
- (转)Jquery最实用的实例及源码(http://www.cnblogs.com/kingfly/archive/2012/12/05/2802539.html)
1:窗口拖动 http://jqueryui.com/resizable/#max-min 2:导航条前后顺序拖动 http://jqueryui.com/sortable/ 3:类似百度首页板块顺序 ...
- 配置文件keepalived.conf详解
keepalived.conf 一个功能比较完整的keepalived 的配置文件,其配置文件keepalived.conf 可以包含三个文本块:全局定义块.VRRP 实例定义块及虚拟服务 ...
- opencv 处女作
显示一幅图:主要是运用功能:imread namedWindow imshowimread:从字面意思我们就可以看懂,用来读取图片的:namedWindow:显然,我们也可以看到这是用来命名窗口名称的 ...
- 使用cookie实现打印浏览记录的功能
可以用cookie知识来实现打印浏览记录.这里面用到的思路是将浏览记录以字符串的方式保存到cookie中,当浏览记录增加时,再将其转化为数组. $uri=$_SERVER['REQUEST_URI'] ...
- 动态加载jar包中的类(方式一)
嘛, 直接上代码 public static class TestClassLoader extends ClassLoader { @Override protected Class<?> ...
- HMC V7.9.0升级至SP2版本
补丁下载地址:http://www-933.ibm.com/support/fixcentral/ 选择补丁版本 MH01405是和ftp://ftp.software.ibm.com/softwar ...
- C# 基础(8)--网络编程
套接字,客户端连接服务器,作为进程通讯机制,是基于描述IP地址和端口,是一个通讯链的句柄,其实质就是两个程序通讯用的. 非常类似于电话插座.双方通话的过程,是一方向电话机发出信号和对方从电话机接受信号 ...