这个题主要考察的是排序思想的应用,虽然可能大部分都知道数组上的排序,但是如果用到链表上,
可能有些人可能就会有人一时想不起来,这道题要求O(nlogn)的算法,所以考虑快排,归并,堆排,
堆排个人认为不怎么好写,这里不做考虑,主要讲一下快排,归并,以及一种直接调用库函数的写法。
首先讲一下最简单的使用库函数的方法,可以说是个投机取巧的方法,直接看代码:
class Solution {
public:
ListNode *sortList(ListNode *head) {
if(head==NULL){
return NULL;
}
vector<int> v;
for(ListNode* p=head;p;p=p->next){
v.push_back(p->val);
}
sort(v.begin(),v.end());
int i=0;
for(ListNode* p=head;p;p=p->next){
p->val=v[i++];
}
return head;
}
};
然后是快排的写法,用了快排的思想,以及交换值:
class Solution {
public:
ListNode *sortList(ListNode *head) {
if(head==NULL){
return NULL;
}
sortList(head,NULL);
return head;
}
void sortList(ListNode *head,ListNode *tail){
if(head==tail)
return;
ListNode *mid=partition(head,tail);
sortList(head,mid);
sortList(mid->next,tail);
}
ListNode* partition(ListNode *node,ListNode *tail){
ListNode *cur=node;
ListNode *next=node->next;
while(next!=tail){
if(next->val<node->val){
cur=cur->next;
swap(cur->val,next->val);
}
next=next->next;
}
swap(cur->val,node->val);
return cur;
}
};
归并的话,主要是归并的思想加上设置一快一慢俩个指针找到链表的中点。
class Solution {
public:
ListNode *sortList(ListNode *head) {
if(head==NULL||head->next==NULL){
return head;
}
ListNode *fast=head->next,*slow=head;
while(fast!=NULL&&fast->next!=NULL){
fast=fast->next->next;
slow=slow->next;
}
ListNode* head2=slow->next;
slow->next=NULL;
ListNode *p1=sortList(head);
ListNode *p2=sortList(head2);
ListNode *p=merge(p1,p2);
return p;
}
ListNode* merge(ListNode* p1,ListNode* p2){
if(p1==NULL) return p2;
if(p2==NULL) return p1;
ListNode* phead;
if(p1->val<p2->val){
phead=p1;
phead->next=merge(p1->next,p2);
}
else{
phead=p2;
phead->next=merge(p1,p2->next);
}
return phead;
}
};