题目:
Sort a linked list in O(n log n) time using constant space complexity.
题意:
使用常量空间对链表进行时间复杂度是O(n log n)的排序。
思路:
首先回忆下时间复杂度是O(nlogn)的排序算法,有归并排序,堆排序,二分插入法等。
我打算使用归并排序来完成。
首先将链表分成两个部分,每个部分是[n/2]大小,然后递归的进行归并排序,只是需要注意的是只允许使用常量空间。若是一般的归并排序,会使用O(N)的空间额外空间。所以进行合并时不需要创建新的链表,只需要使用将链表进行有序合并的方法,这道题之前出现过。
以上。
代码如下:
/**
* 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) {
if(head == NULL || head->next == NULL)return head;
return mergeSort(head);
}
ListNode* mergeSort(ListNode* head) {
if(head == NULL || head->next == NULL)return head;
if(head->next->next == NULL) {
if(head->val > head->next->val){
swap(head->val, head->next->val);
}
return head;
}
ListNode* tmp = head;
ListNode* tmp2 = head->next;
ListNode* last = NULL;
while(tmp2 != NULL) {
last = tmp;
tmp = tmp->next;
tmp2 = tmp2->next;
if(tmp2 == NULL)break;
tmp2 = tmp2->next;
}
tmp = last;
tmp2 = tmp->next;
tmp->next = NULL;
head = mergeSort(head);
tmp2 = mergeSort(tmp2);
ListNode* h = NULL;
if(head->val < tmp2->val) {
h = head;
head = head->next;
}
else {
h = tmp2;
tmp2 = tmp2->next;
}
ListNode* current = h;
while(head != NULL && tmp2 != NULL) {
if(head->val < tmp2->val) {
current->next = head;
head = head->next;
}
else {
current->next = tmp2;
tmp2 = tmp2->next;
}
current= current->next;
}
if(head != NULL)current->next = head;
else if(tmp2 != NULL)current->next = tmp2;
return h;
}
};