Sort a linked list in O(n log n) time using constant space complexity.
这道题我看了答案之后才想出来自己敲出来的。
做这道题要知道两个知识, 首先是排序,另外一个是 之前有一道Easy系列的题目,有序链表的排序法(做过) 那就很简单了。
排序时间 复杂度是 O(n log n), 想到快速排序法和归并排序法, 快速复杂度是一般是O(n log n), 有时候不好的情况下是n^2,所有选择归并排序法。
归并排序发 ,不停的二分,分成有序的链表进行排序,减小了很大重复度。 归并排序法能百度出来,下面不多说,贴上我的AC代码。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* MergeSort(struct ListNode* head,int length);
//struct ListNode* sortList(struct ListNode* head);
struct ListNode* mergeSortedTwoLists(struct ListNode* p1, struct ListNode* p2) ;
struct ListNode* sortList(struct ListNode* head) {
if(head==NULL)
return head;
int length=0;
struct ListNode* pCurrent=head;
while(pCurrent!=NULL)
{
length++;
pCurrent=pCurrent->next;
}
head=MergeSort(head,length);
return head;
}
//*******************精简排序两个有序链表***************%%
struct ListNode* mergeSortedTwoLists(struct ListNode* p1, struct ListNode* p2)
{
//p1half,p2half,长度是1返回其本身,所有长度肯定比1大..
//倒数,从小到大,把小的放前面
struct ListNode* MergedLists=NULL; //头节点
if (p1->val<=p2->val)
{
MergedLists=p1;
p1=p1->next; //为什么变0了?
MergedLists->next=NULL;
}
else
{
MergedLists=p2;
p2=p2->next;
MergedLists->next=NULL;
}
//确定第一个
struct ListNode* pCurrent=(struct ListNode*)malloc(sizeof(struct ListNode));
pCurrent=MergedLists; //当前节点,指向MegedList
while (p1!=NULL&&p2!=NULL)
{
if (p1->val<p2->val)
{
pCurrent->next=p1; //接着下面
p1=p1->next;
}
else
{
pCurrent->next=p2; //接着下面
p2=p2->next;
}
pCurrent=pCurrent->next;
}
if (p1==NULL)
{
while(p2!=NULL)
{
pCurrent->next=p2; //接着下面
p2=p2->next;
pCurrent=pCurrent->next;
pCurrent->next=NULL;
}
}
else
{
while(p1!=NULL)
{
pCurrent->next=p1; //接着下面
p1=p1->next;
pCurrent=pCurrent->next;
pCurrent->next=NULL;
}
}
return MergedLists;
}
struct ListNode* MergeSort(struct ListNode* head,int length)
{
if(length==1)
return head;
struct ListNode* p1half=head;
struct ListNode* p2half=head;
int mid=length/2;
int i=1;
while(i<mid)
{
i++;
if(p2half!=NULL)
{
p2half=p2half->next;
}
else
break;
}
if(p2half!=NULL)
{
struct ListNode* p1buttom=p2half;
p2half=p2half->next;
p1buttom->next=NULL; //在中间一个之前断开,形成两个链表
}
p1half=MergeSort(p1half,mid);
p2half=MergeSort(p2half,length-mid);
head=mergeSortedTwoLists(p1half,p2half); //对两个链表就行排序合并
return head;
}
有不对的地方,欢迎大家指正与批评,谢谢大家。~