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的更多相关文章

  1. LeetCode—-Sort List

    LeetCode--Sort List Question Sort a linked list in O(n log n) time using constant space complexity. ...

  2. [LeetCode] Sort Characters By Frequency 根据字符出现频率排序

    Given a string, sort it in decreasing order based on the frequency of characters. Example 1: Input: ...

  3. [LeetCode] Sort List 链表排序

    Sort a linked list in O(n log n) time using constant space complexity. 常见排序方法有很多,插入排序,选择排序,堆排序,快速排序, ...

  4. [LeetCode] Sort Colors 颜色排序

    Given an array with n objects colored red, white or blue, sort them so that objects of the same colo ...

  5. [leetcode]Sort Colors @ Python

    原题地址:https://oj.leetcode.com/problems/sort-colors/ 题意: Given an array with n objects colored red, wh ...

  6. LeetCode: Sort List 解题报告

    Sort List Sort a linked list in O(n log n) time using constant space complexity. 使用Merge Sort, 空间复杂度 ...

  7. LeetCode Sort List 链表排序(规定 O(nlogn) )

    Status: AcceptedRuntime: 66 ms 题意:根据给出的单链表,用O(nlogn)的时间复杂度来排序.由时间复杂度想到快排.归并这两种排序.本次用的是归并排序.递归将链表的规模不 ...

  8. [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( ...

  9. 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( ...

随机推荐

  1. [题解]vijos 运输计划

    Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家 ...

  2. poj 1236 Network of Schools(连通图)

    题目链接:http://poj.org/problem?id=1236 题目大意:有一些学校,学校之间可以进行收发邮件,给出学校的相互关系,问:1.至少 要向这些学校发送多少份才能使所有的学校都能获得 ...

  3. EF 连接MySQL 数据库  保存中文数据后乱码问题

    EF 连接MySQL 数据库  保存中文数据后乱码问题 采用Code First 生成的数据库,MySQL数据库中,生成的表的编码格式为***** 发现这个问题后,全部手动改成UTF8(图是另一个表的 ...

  4. 【经验】Maven Tomcat8+ 实现自动化部署

    1.配置tomcat-users.xml 首先在Tomcat里配置deploy的用户(tomcat根目录/conf/tomcat-users.xml): <role rolename=" ...

  5. 【经验记录】Jconsole Jvisualvm 监控Tomcat

    环境:centos 6 1.首先检查hostname是否正确,输入以下命令 hostname -i 如果输出机器ip,则表示正确,如果输出 hostname: Unknown host 查看/etc/ ...

  6. Android环境配置及运行helloWord案例

      Android的环境搭建步骤,以及输出一个helloWorder 1:下载Android开发环境   及是: SDK adt-bundle-windows-x86_64-20140702 此时的版 ...

  7. 自定义View(三)实现简单的可拖动、可缩放的ImageView

    实现技术主要用到1.多点触摸  2.matrix的矩阵,平移.缩放 根据手指的数量判断是进行的拖动.还是缩放动作 package com.bi.xintest; import android.cont ...

  8. poj 2104 K-th Number (划分树入门 或者 主席树入门)

    题意:给n个数,m次询问,每次询问L到R中第k小的数是哪个 算法1:划分树 #include<cstdio> #include<cstring> #include<alg ...

  9. SQLserver聚集表、堆和索引

    SQL Server 表使用下列两种方法之一来组织其分区中的数据页: 聚集表是有聚集索引的表.数据行基于聚集索引键按顺序存储.聚集索引按 B 树索引结构实现,B 树索引结构支持基于聚集索引键值对行进行 ...

  10. centos查看系统cpu个数、核心书、线程数

    1.查看物理cpu个数 grep 'physical id' /proc/cpuinfo | sort -u | wc -l 2.查看核心数量 grep 'core id' /proc/cpuinfo ...