Sort a linked list in O(n log n) time using constant space complexity.
自己写了快排的想法,不过实现的很蛋疼,加上搜索的了其他的人的想法,总结了基本的3种实现方法
第一种:快排的思想,输出结果一直没问题,提交就提示Time Limit Exceeded,调了好久没用,后来参考:http://blog.csdn.net/ashqal/article/details/17356057 发现:每次取head作为mid,把链表分为三个部分:小于mid,等于mid和大于mid,然后对小于大于mid的部分进行排序,这样 当参考值相同的时候,应该将值放到参考值链表(等于mid的表)中,减少了大量重复排序工作
class Solution {
public:
ListNode *sortList(ListNode *head) {
if(head == NULL || head->next == NULL) return head;
ListNode *p = head->next, *q = head,*mid = head,*mid_back = head;
while(p != NULL){
if(p->val < mid->val){
q->next = p->next;
p->next = head;
head = p;
p = q->next;
}else if(p->val == mid->val){
if(mid_back->next != p){
q->next = p->next;
p->next = mid_back->next;
mid_back->next = p;
p = q->next;
}else{
mid_back = p;
q = p;
p=p->next;
}
}else{
p = p->next;
q = q->next;
}
}
ListNode *temp1 = sortList(mid_back->next);
ListNode *m = head;
if(m == mid){
mid_back->next = temp1;
return mid;
}
while(m->next!= mid){
m=m->next;
}
m->next = NULL;
ListNode *temp2 = sortList(head);
ListNode *n = temp2;
while(n->next!= NULL)n=n->next;
n->next = mid;
mid_back->next = temp1;
return temp2;
}
};
第二种:利用了Map 原文:http://blog.csdn.net/doc_sgl/article/details/16371025
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *sortList(ListNode *head) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if(head == NULL|| head->next == NULL)return head;
map<int, vector<ListNode*>> mp;
ListNode* pnode = head;
while(pnode)
{
mp[pnode->val].push_back(pnode);
pnode = pnode->next;
}
map<int, vector<ListNode*>>::iterator it = mp.begin();
head = NULL;
ListNode* cur = NULL;
for(; it != mp.end(); it++)
{
vector<ListNode*> vec = (*it).second;
for(int i = 0; i < vec.size(); i++)
{
if(head == NULL){
head = vec[i];
cur = vec[i];
}else{
cur->next = vec[i];
cur = cur->next;
}
}
}
cur->next = NULL;
return head;
}
};
第三种:
原文:http://blog.csdn.net/xudli/article/details/16819545帖子中,利用了归并的思想,貌似更易理解了
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *sortList(ListNode *head) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
//merge sort
return mergeSort(head);
}
ListNode* mergeSort(ListNode* head) {
if(head==NULL || head->next==NULL) return head;
//split
ListNode* p=head; ListNode* q=head;
ListNode* pre = p;
while(q!=NULL && q->next!=NULL) {
q=q->next->next;
pre = p;
p=p->next;
}
pre->next = NULL;
ListNode* h1 = mergeSort(head);
ListNode* h2 = mergeSort(p);
return merge(h1,h2);
}
ListNode* merge(ListNode* h1, ListNode* h2) {
ListNode* dump = new ListNode(0);
ListNode* p = dump;
while(h1!=NULL && h2!=NULL) {
if(h1->val<h2->val){
p->next = h1;
h1 = h1->next;
} else {
p->next = h2;
h2 = h2->next;
}
p = p->next;
}
if(h1!=NULL) p->next = h1;
else p->next = h2;
ListNode* head = dump->next;
delete dump;
return head;
}
};