148. 排序链表
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
解题思路: 此题考查归并排序,即使题目不给定时间复杂度的限制,其实也应该用归并排序解题,归并排序最适合解决链表排序的问题。而恰好归并排序的时间复杂度为
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)。下面阐述一下解题思路,先用快慢指针找到链表的中位点,将链表断开,然后对两端链表分别排序,然后再合并两个链表。此题参考了Grandyang博客的解法。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* merge(ListNode *head, ListNode *tmp) {
ListNode *dummy = new ListNode(-1), *cur = dummy;
while (head && tmp) {
if (head->val < tmp->val) {
cur->next = head;
head = head->next;
} else {
cur->next = tmp;
tmp = tmp->next;
}
cur = cur->next;
}
if (head) cur->next = head;
else cur->next = tmp;
ListNode *res = dummy->next;
delete dummy;
return res;
}
ListNode* sortList(ListNode* head) {
if (!head ||!head->next) return head;
ListNode *slow = head, *fast = head, *pre = NULL;
while (fast && fast->next) {
fast = fast->next->next;
pre = slow;
slow = slow->next;
}
pre->next = NULL;
return merge(sortList(head), sortList(slow));
}
};