题意
在 O(nlogn) 的时间和 O(1) 的空间内对一个链表进行排序
思路
分治法:归并排序
分治法的基本思路:Devide and Conquer
对于该题:
- 找到链表中点,并将其从中间拆成两条链表
- 对这两条链表分别进行归并排序
- 将这两条链表进行归并
时间复杂度:devide需要进行 O(logn) 次,归并的时间复杂度是 O(n) ,因此是 O(nlogn)
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* GetMid(ListNode* head) {
if (!head) return NULL;
ListNode* slow = head;
ListNode* fast = head->next;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
ListNode* Merge(ListNode* head1, ListNode* head2) {
ListNode* vhead = new ListNode(0);
ListNode* now = vhead;
while (head1 || head2) {
if (head1 && head2) {
if (head1->val < head2->val) {
now->next = head1;
head1 = head1->next;
} else {
now->next = head2;
head2 = head2->next;
}
} else if (head1) {
now->next = head1;
head1 = head1->next;
} else {
now->next = head2;
head2 = head2->next;
}
now = now->next;
}
ListNode* head = vhead->next;
delete(vhead);
return head;
}
ListNode* MergeSort(ListNode* head) {
if (!(head->next)) return head;
ListNode* mid = GetMid(head);
ListNode* head1 = head;
ListNode* head2 = mid->next;
mid->next = NULL;
head1 = MergeSort(head1);
head2 = MergeSort(head2);
ListNode* newhead = Merge(head1, head2);
return newhead;
}
ListNode* sortList(ListNode* head) {
if (!head) return NULL;
return MergeSort(head);
}
};