Sort a linked list in O(n log n) time using constant space complexity.
题意实现一个链表排序的算法;
方法一:刚开始想的是自己定义个比较函数,然后调用sort()函数进行实现
[cpp] view plain copy
class Solution
{
public:
static bool cmp(ListNode* a, ListNode* b)
{
return a->val < b->val;
}
ListNode* sortList(ListNode* head)
{
if (head==NULL)
{
return head;
}
vector<ListNode*> arrList;
ListNode* p = head;
while (p)
{
arrList.push_back(p);
p = p->next;
}
sort(arrList.begin(), arrList.end());
p = head = arrList[0];
for (int i=1; i<arrList.size(); i++)
{
p->next = arrList[i];
p = p->next;
}
arrList[arrList.size() - 1]->next = NULL;
return head;
}
};
方法二:因为题目要求的时间负责度O(nlogn), 故可以考虑归并排序的思想;
归并排序的一把步骤:
(1)将待排序数组去中间点并一分为二;
(2)递归地对左半部分进行归并排序;
(3)递归地对右半部分进行归并排序;
(4)将两个半部分进行合并,得到结果;
所以对应此题,可以分为三个小问题;
(1)找到链表中点;
(2)写出merge函数,即如何合并链表
(3)写出mergesort函数,实现上述步骤;
[cpp] view plain copy
class Solution
{
public:
//找到链表中间位置
ListNode* findMid(ListNode* head)
{
ListNode* slow = head;
ListNode* fast = head;
while (fast!=NULL && fast->next!=NULL && fast->next->next!=NULL)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
//合并两个有序链表
ListNode* mergeList(ListNode* h1, ListNode* h2)
{
if (h1 == NULL)
{
return h2;
}
else if (h2 == NULL)
{
return h1;
}
else
{
ListNode* head = NULL;
if (h1->val>h2->val)
{
head = h2;
h2 = h2->next;
}
else
{
head = h1;
h1 = h1->next;
}
ListNode* p = head;
while (h1 && h2)
{
if (h1->val < h2->val)
{
p->next = h1;
h1 = h1->next;
}
else
{
p->next = h2;
h2 = h2->next;
}
p = p->next;
}
if (h1) p->next = h1;
if (h2) p->next = h2;
return head;
}
}
ListNode* sortList(ListNode* head)
{
if (head == NULL || head->next == NULL)
{
return head;
}
ListNode* mid = findMid(head);
ListNode* h2 = sortList(mid->next);
mid->next = NULL;
ListNode* h1 = sortList(head);
return mergeList(h1, h2);
}
};