148. Sort List**
https://leetcode.com/problems/sort-list/
题目描述
Sort a linked list in O(n log n)
time using constant space complexity.
Example 1:
Input: 4->2->1->3
Output: 1->2->3->4
Example 2:
Input: -1->5->3->4->0
Output: -1->0->3->4->5
C++ 实现 1
归并排序, 归并两个链表的方法可以参考 21. Merge Two Sorted Lists*, 代码不难; 对于链表的重点, 可以使用快慢指针进行查找, 比如可以参考 141. Linked List Cycle* .
class Solution {
private:
ListNode* merge(ListNode *llist, ListNode *rlist) {
ListNode *dummy = new ListNode(0);
auto p = dummy;
while (llist && rlist) {
if (llist->val < rlist->val) {
p->next = llist;
llist = llist->next;
} else {
p->next = rlist;
rlist = rlist->next;
}
p = p->next;
}
p->next = llist ? llist : rlist;
return dummy->next;
}
public:
ListNode* sortList(ListNode* head) {
if (!head || !head->next) return head;
ListNode *dummy = new ListNode(0);
dummy->next = head;
// 使用快慢指针来找到链表的中点, 这里要强调一点为什么 slow 初始化为
// dummy 而 fast 初始化为 head, 也就是说, 初始化的时候, slow 应该要比
// fast 慢上一步才行, 否则对于链表 1 -> 2 -> NULL, 如果 fast 和 slow 初始化
// 都是 1, 那么当 while 循环结束后, slow 就会指向 2, 最终 leftHead 仍然是
// 1 -> 2 -> NULL, 而 rightHead 就是 NULL, 这是不对的, 之后 sortList 处理
// leftHead 就会造成无限循环. 只有当 while 结束时, slow 指向 1, 才是我们想要的,
// 所以初始 slow 设置为 dummy. 另外 slow->next=nullptr, 让前半部分链表结尾为空,
// 毕竟 merge 函数中要求的就是两个链表以空指针结尾.
auto slow = dummy, fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
auto rlist = sortList(slow->next);
slow->next = nullptr; // 这一步不要忘了,以免节点指向混乱.
auto llist = sortList(dummy->next);
return merge(llist, rlist);
}
};