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) 知识点:归并排 ...
随机推荐
- hdu1255(线段树——矩形面积交)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 题意:求N个矩形中,求被覆盖至少俩次的面积和 分析:覆盖两次即col[rt]>=2就好.一 ...
- 自己定义 ViewGroup 支持无限循环翻页之三(响应回调事件)
大家假设喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处,再次感谢 ################################ ...
- Android中Broadcast Receiver组件具体解释
BroadcastReceiver(广播接收器)是Android中的四大组件之中的一个. 以下是Android Doc中关于BroadcastReceiver的概述: ①广播接收器是一个专注于接收广播 ...
- Java调用cmd压缩文件
今天在做一个java调用windows的压缩命令时遇到一奇怪问题代码如下: String cmd ="C:/Program Files (x86)/WinRAR/rar.exe a c:/t ...
- UML之部署图(Deployment Diagram)
计算机系统由硬件和软件组成,应用软件的命令,先转化为操作系统命令,再转化为汇编语言,最后再转化为二进制命令,由硬件来运行.软件要部署到硬件上才具有生命.Deployment Diagram展示的就是把 ...
- Android使用应用程序资源(、颜色数组、尺寸、弦、布尔、整型)
一.Android资源分类详细解释 1.Android资源类别 Android中的资源分为两大类 : 可直接訪问的资源, 无法直接訪问的原生资源; -- 直接訪问资源 : 这些资源能够使用 R. ...
- winfrom 倒计时控件
最近在做一个快递柜项目,要求在用户没有操作的时间到了一分钟,自动返回主页,我于是封装了一个倒计时控件,废话少说,直接上代码 public partial class RemainingTimeUC : ...
- POJ 3181 Dollar Dayz 简单DP
这DP虽然简单 但是思考一下还是挺好的 题意是 1,2,3,4....k 用加法凑成N 每个数可取不限个数 令dp[i][j] 表示前i种数凑成j的方案数 然后dp[i][j] = dp[i - 1] ...
- 使用psftp.exe
使用psftp.exe 点击打开psftp.exe,出现如下图的命令窗口.
- 解决alaert.builder二次调用报错的bug
报错的代码是: The specified child already has a parent. You must call removeView() on the child's parent f ...