LeetCode之Sort List
称号: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的更多相关文章
- C#版 - LeetCode 148. Sort List 解题报告(归并排序小结)
leetcode 148. Sort List 提交网址: https://leetcode.com/problems/sort-list/ Total Accepted: 68702 Total ...
- 待字闺中之快排单向链表;leetcode之Sort List
题目来源.待字闺中.原创@陈利人 .欢迎大家继续关注微信公众账号"待字闺中" 分析:思路和数据的高速排序一样,都须要找到一个pivot元素.或者节点. 然后将数组或者单向链表划分为 ...
- LeetCode——Insertion Sort List
LeetCode--Insertion Sort List Question Sort a linked list using insertion sort. Solution 我的解法,假设第一个节 ...
- [LeetCode] Wiggle Sort II 摆动排序
Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]... ...
- [LeetCode] Wiggle Sort 摆动排序
Given an unsorted array nums, reorder it in-place such that nums[0] <= nums[1] >= nums[2] < ...
- [LeetCode] Insertion Sort List 链表插入排序
Sort a linked list using insertion sort. 链表的插入排序实现原理很简单,就是一个元素一个元素的从原链表中取出来,然后按顺序插入到新链表中,时间复杂度为O(n2) ...
- 【Leetcode】Sort List JAVA实现
Sort a linked list in O(n log n) time using constant space complexity. 1.分析 该题主要考查了链接上的合并排序算法. 2.正确代 ...
- [LeetCode] 148. Sort List 解题思路
Sort a linked list in O(n log n) time using constant space complexity. 问题:对一个单列表排序,要求时间复杂度为 O(n*logn ...
- 【LeetCode】 sort list 单清单归并
称号:Sort a linked list in O(n log n) time using constant space complexity. 思路:要求时间复杂度O(nlogn) 知识点:归并排 ...
随机推荐
- 云计算分布式大数据神器Spark实战高手之旅
从2012年1月份研究Spark到如今已经两年多的时间了. 在这两年多的时间里比較彻底的研究了Spark的源码并已经在2014年4月24日编写完毕了世界上第一本Spark书籍. 鉴于CSDN在大陆IT ...
- Android开展:ADT+Eclipse使用错误:Text editor does not have a document provider
Eclipse参加Android sdk源代码 正在使用Eclipse进行Android开发时间,我们经常需要导入sdk源代码来Eclipse中,方便api阅读和查询,详细操作为:ctrl+鼠标左键. ...
- M3U8格式解说及实际应用分析
M3U8有啥优点 ? 网上搜索了一下,大家众说纷纭,个人理解主要是能够做多码率的适配,依据网络带宽,client会选择一个适合自己码率的文件进行播放,保证视频流的流畅. 在IOS device和mac ...
- el表达式 分页提交 中文乱码
el表达式 分页提交 中文乱码 网上找了很多资料,没能解决我的问题.并不是说网上的那些资料不好.而是不适用于我的问题吧. 看看的的问题: 原始页面 单击下一页 , 乱码. 引起的原因则是因为自己的js ...
- Java 理论与实践: 处理 InterruptedException(转)
很多 Java™ 语言方法,例如 Thread.sleep() 和 Object.wait(),都可以抛出InterruptedException.您不能忽略这个异常,因为它是一个检查异常(check ...
- HiPAC高性能规则匹配算法之查找过程
收到一封邮件,有位朋友认为我误解了nf-HiPAC.如此的一个高性能算法怎能被什么传统的hash,tree之类的胁迫.是啊.HiPAC是一个非常猛的算法.文档也比較少,这就更加添加了其神奇感,可是这决 ...
- 要引入java吸管工具
Java调用颜色选择器robot方法getPixelColor让我们来看看下面的方法robot详细的实施类方法中,例如,下面的 getPixelColor public Color getPixelC ...
- 【设计优化】-使用缓冲(Buffer)提高程序性能
缓冲区是一块特定的内存区域.开辟缓冲区的目的是通过缓解应用程序上下层之间的性能差异,提高系统性能. 缓冲能够协调上层组件和下层组件的性能差异.当上层组件性能因为下层组件时,能够有效地降低上层组件对下层 ...
- Git代理服务器设置和访问Github
因为现在工作的网络环境有着非常严格的限制,.可以说,在最近的访问通过代理Github它采取了一些曲折的.也积累了一些相关经验.我们认为有必要注意什么. 符合"不要再发明轮子"宗旨, ...
- c++学习笔记4,调用派生类的顺序构造和析构函数(一个)
测试源代码: //測试派生类的构造函数的调用顺序何时调用 //Fedora20 gcc version=4.8.2 #include <iostream> using namespace ...