Sort a linked list in O(n log n) time using constant space complexity.
这道题是要求对单链表进行排序,有个O(nlogn)的时间复杂度的要求。
我的想法是采取类似头插法的方式,遍历链表结点,设3个指针,min指向当前链表中的最小值,max指向当前链表中的最大值,cur指向前一插入的值。
- min , max , cur 初始时都指向第一个元素。
- 从第二个元素开始,如果该元素的值小于等于min,则把该结点插入到min之前;
- 如果该元素的值大于等于max,则把该结点插入max之后;
- 如果该元素小于cur的值,则从min开始寻找插入位置;否则从cur开始查找插入位置。
下面贴上代码:
class Solution {
public:
ListNode* sortList(ListNode* head){
ListNode *min=head,*max=head,*cur=head;
ListNode *p= (head!=NULL)?head->next:head;
ListNode *q=NULL;
while(p){
q=p->next;
if(p->val<=min->val){
p->next=min;
min=p;
}else if(p->val>=max->val){
max->next=p;
max=p;
}else if(p->val<cur->val){
ListNode* f=new ListNode(0);
f->next=min;
while(f->next->val<p->val){
f=f->next;
}
p->next=f->next;
f->next=p;
cur=p;
}else{
ListNode* f=cur;
while(f->next->val<p->val){
f=f->next;
}
p->next=f->next;
f->next=p;
cur=p;
}
p=q;
}
if(head!=NULL)
max->next=NULL;
return min;
}
虽然AC了但是效率并不高,感觉test case不是够全面啊,一开始想到的是用归并排序的思想,但是没想到怎么快速定位到中间位置的结点,后来看到discuss里的一个人分享的,才恍然大悟QAQ
ListNode* getMid(ListNode* p) {
if (!p) {
return NULL;
}
ListNode* f = p->next;
ListNode* s = p;
while(f && f->next) {
f = f->next->next;
s = s->next;
}
return s;
}