https://leetcode.com/problems/sort-list/
归并排序。须要解决的两个基础问题:
- 找链表中点(快慢指针)
- 合并两个排序链表(https://leetcode.com/problems/merge-two-sorted-lists/)
C++
class Solution {
public:
ListNode* sortList(ListNode* head) {
if (!head || !head->next) return head;
ListNode *mid = findMid(head);
ListNode *right = mid->next;
mid->next = NULL;
ListNode *l = sortList(head);
ListNode *r = sortList(right);
return mergeTwoLists(l, r);
}
ListNode* findMid(ListNode* head) {
ListNode *slow = head, *fast = head;
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode dummy(0);
ListNode *cur = &dummy;
while (l1 && l2) {
if (l1->val < l2->val) {
cur->next = l1;
l1 = l1->next;
} else {
cur->next = l2;
l2 = l2->next;
}
cur = cur->next;
}
cur->next = l1 ? l1 : l2;
return dummy.next;
}
};
另外,我也写了快速排序,但是由于数据的关系会超时。LeetCode的discuss中提到的解决方法是使用random pivot或者skip duplicates,就不去折腾了。关键是理清基本思想,也贴在这里吧。
class ReturnType {
public:
ListNode *start, *end;
ReturnType(ListNode *p1, ListNode *p2) {
this->start = p1;
this->end = p2;
}
};
class Solution {
public:
/**
* @param head: The first node of linked list.
* @return: You should return the head of the sorted linked list,
using constant space complexity.
*/
ListNode *sortList(ListNode *head) {
if (!head || !head->next) return head;
return quick_sort(head).start;
}
ReturnType quick_sort(ListNode *head) {
if (!head) return ReturnType(NULL, NULL);
if (!head->next) return ReturnType(head, head);
ListNode dummy_left(0), dummy_right(0);
ListNode *l = &dummy_left, *r = &dummy_right;
// partition
ListNode *pivot = head;
head = head->next;
while (head) {
if (head->val < pivot->val) { l->next = head; l = l->next; }
else { r->next = head; r = r->next; }
head = head->next;
}
l->next = NULL; r->next = NULL;
// quick sort
ReturnType ret1 = quick_sort(dummy_left.next);
ReturnType ret2 = quick_sort(dummy_right.next);
// re-connect
ReturnType ret(NULL, NULL);
if (ret1.end) { ret1.end->next = pivot; ret.start = ret1.start; }
else ret.start = pivot;
pivot->next = ret2.start;
if (ret2.end) ret.end = ret2.end;
else ret.end = pivot;
return ret;
}
};
相关: http://www.cnblogs.com/ilovezyg/p/6372759.html