称号:Sort a linked list in O(n log n) time using constant space complexity.

对一个单链表进行排序,要求时间复杂度为O(n log n),空间复杂度为常量

分析:在排序中高速排序,堆排序,归并排序等都是能够在O(n log n)的时间复杂度之内完毕的。

a)      高速排序能够进行空间复杂度为1的原地排序,但必须是在能够反向索引的情况下。比如通过下标的减法向前索引。或者通过双向指针进行索引(双向链表)。

b)      堆排序必需要大小为n的额外空间,不考虑。

c)       归并排序理论上也是须要n的额外空间的(合并的时候),可是考虑到此次是链表的特殊情况。能够借助链表的插入这样的方式进行破坏性的操作来达到排序的目的。即不改变每一个节点中的元素,每次到合并的时候就通过改动next指针又一次组成一条新的链表。终于达到常量空间O(n log n)时间的单链表排序,详细细节见代码。

代码例如以下:

在leetcode中提交时。仅仅需拷贝class中的函数就可以,此处完整的cpp文件是为了更好的模拟运行过程

#include<iostream>
using namespace std; //Sort a linked list in O(n log n) time using constant space complexity.
//尝试使用归并排序,待排序元素为单链表
struct ListNode {
int val;
ListNode *next;
}; class Solution {
public:
ListNode *sortList(ListNode *head)
{
ListNode * retHead = NULL;
int listLen = GetLen(head);
if (listLen < 2)
{
return head;
}
retHead = MergeSort(head,listLen);
return retHead; } //获取距离head长度为len-1距离的节点指针
ListNode* GetMid(ListNode*head , int len)
{
ListNode *temp = head;
for (int i = 1; i< len; i++)
{
head = head->next;
}
return head;
} //归并排序
ListNode* MergeSort(ListNode* head, int len)
{
if (len == 1)
{
return head;
}
int mid = len/2;
ListNode *secondHead = GetMid(head, mid+1);
head = MergeSort(head, mid);
secondHead = MergeSort(secondHead,len-mid);
head = CombinList(head,mid,secondHead,len-mid);
return head;
} //为了降低储存空间,仅仅有破坏链表的原有结构,重组链表达到排序的目的
ListNode* CombinList(ListNode *pList1,int len1, ListNode* pList2,int len2)
{
int sum = len1+len2;
ListNode* retHead = NULL;
ListNode* retTail = NULL;
ListNode* nextLink = GetMid(pList2,len2+1); //指向下一条链表的头结点
ListNode * exList = NULL; //用于指向交互结点的指针 if (pList1->val > pList2->val) //确定返回的头结点
{
retHead = pList2;
pList2 = pList2->next;
len2--;
}
else
{
retHead = pList1;
pList1 = pList1->next;
len1--; }
retTail = retHead;
while (len1 != 0 && len2 != 0)
{
if (pList1->val > pList2->val)
{
retTail->next = pList2;
retTail= retTail->next;
pList2 = pList2->next;
len2--;
}
else
{
retTail->next = pList1;
retTail=retTail->next;
pList1 = pList1->next;
len1--;
}
} if (len1 == 0)
{
retTail->next = pList2;
}
else
{
retTail->next = pList1;
while (len1 > 1)
{
pList1= pList1->next;
len1--;
}
pList1->next = nextLink;
}
return retHead;
} //获取链表的长度,时间复杂度为n
int GetLen(ListNode *head)
{
int len = 0;
while (head!=NULL)
{
len++;
head = head->next;
}
return len;
}
}; void printList(ListNode* head)
{
cout<<endl;
while (head != NULL)
{
cout<<head->val<<" ";
head=head->next; }
cout<<endl;
}
int main()
{
ListNode *head = new ListNode;
ListNode *tail = head;
head->val = 4;
head->next = NULL;
for (int i = 0; i< 19; i++)
{
ListNode* temp = new ListNode;
temp->val = rand()%90;
temp->next = NULL;
tail->next = temp;
tail = tail->next;
}
printList(head);
Solution a;
head = a.sortList(head);
printList(head);
system("pause");
return 0;
}

模拟排序前后结果为:

版权声明:本文博主原创文章,博客,未经同意不得转载。

LeetCode之Sort List的更多相关文章

  1. C#版 - LeetCode 148. Sort List 解题报告(归并排序小结)

    leetcode 148. Sort List 提交网址: https://leetcode.com/problems/sort-list/  Total Accepted: 68702 Total ...

  2. 待字闺中之快排单向链表;leetcode之Sort List

    题目来源.待字闺中.原创@陈利人 .欢迎大家继续关注微信公众账号"待字闺中" 分析:思路和数据的高速排序一样,都须要找到一个pivot元素.或者节点. 然后将数组或者单向链表划分为 ...

  3. LeetCode——Insertion Sort List

    LeetCode--Insertion Sort List Question Sort a linked list using insertion sort. Solution 我的解法,假设第一个节 ...

  4. [LeetCode] Wiggle Sort II 摆动排序

    Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]... ...

  5. [LeetCode] Wiggle Sort 摆动排序

    Given an unsorted array nums, reorder it in-place such that nums[0] <= nums[1] >= nums[2] < ...

  6. [LeetCode] Insertion Sort List 链表插入排序

    Sort a linked list using insertion sort. 链表的插入排序实现原理很简单,就是一个元素一个元素的从原链表中取出来,然后按顺序插入到新链表中,时间复杂度为O(n2) ...

  7. 【Leetcode】Sort List JAVA实现

    Sort a linked list in O(n log n) time using constant space complexity. 1.分析 该题主要考查了链接上的合并排序算法. 2.正确代 ...

  8. [LeetCode] 148. Sort List 解题思路

    Sort a linked list in O(n log n) time using constant space complexity. 问题:对一个单列表排序,要求时间复杂度为 O(n*logn ...

  9. 【LeetCode】 sort list 单清单归并

    称号:Sort a linked list in O(n log n) time using constant space complexity. 思路:要求时间复杂度O(nlogn) 知识点:归并排 ...

随机推荐

  1. SE 2014年5月25日

    如图配置 两实验 R1模拟总部,R2 与R3模拟分部 实验一  要求使用 IPSec VPN 主模式,使得总部与两分部内网可相互通讯 步骤: 1.  配置默认路由 [RT1]ip route-stat ...

  2. 【译】ASP.NET MVC 5 教程 - 7:Edit方法和Edit视图详解

    原文:[译]ASP.NET MVC 5 教程 - 7:Edit方法和Edit视图详解 在本节中,我们继续研究生成的Edit方法和视图.但在研究之前,我们先将 release date 弄得好看一点.打 ...

  3. Python数据结构-字典

    tel={,} tel[ print(tel) print(tel['tom']) del tel['tom'] print(tel) print(tel.keys()) 运行结果: {, , } { ...

  4. poj3176--Cow Bowling(dp:数塔问题)

    Cow Bowling Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14028   Accepted: 9302 Desc ...

  5. 也说Javascript对象拷贝及疑问

    一.浅拷贝 当我们需要将一个对象拷贝至另一个对象时,我们一般会这么实现 function shadowCopy(source,target){ var target=target||{}; for(v ...

  6. Hibernate4 : 持久化你的第一个类

    由于目前我在学校的一个实验室跟老师学习Java EE开发,老师用的是Seam框架接活做项目,所以这一系列的文章将会向Seam方向写..路线大致应该是 : JSP --> Servlet --&g ...

  7. Windows Phone开发(16):样式和控件模板

    原文:Windows Phone开发(16):样式和控件模板 在前面资源一文中也提过样式,样式就如同我们做HTML页排版时常用到的CSS样式表,它是对于特定娄型的可视化元素,应该可以直接说是针对控件的 ...

  8. JDK源码学习系列05----LinkedList

                                             JDK源码学习系列05----LinkedList 1.LinkedList简介 LinkedList是基于双向链表实 ...

  9. Linux在高铁项目的部署环境

    因为Linux和Java像开源.所以,现在在server基本上使用部署Linux平台即server.然后部署项目.在开发项目的过程中.程序员绝大多数仍采用最经典windows操作系统,尽管Linux也 ...

  10. DP:树DP

    The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...