Sort a linked list in O(n log n) time using constant space complexity.
因为题目要求复杂度为O(nlogn),故可以考虑归并排序的思想。
归并排序的一般步骤为:
1)将待排序数组(链表)取中点并一分为二;
2)递归地对左半部分进行归并排序;
3)递归地对右半部分进行归并排序;
4)将两个半部分进行合并(merge),得到结果。
所以对应此题目,可以划分为三个小问题:
1)找到链表中点 (快慢指针思路,快指针一次走两步,慢指针一次走一步,快指针在链表末尾时,慢指针恰好在链表中点);
2)写出merge函数,即如何合并链表。 (见merge-two-sorted-lists 一题解析)
3)写出mergesort函数,实现上述步骤
class Solution { public: ListNode* findMiddle(ListNode* head){ ListNode* chaser = head; ListNode* runner = head->next; while(runner != NULL && runner->next != NULL){ chaser = chaser->next; runner = runner->next->next; } return chaser; } ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if(l1 == NULL){ return l2; } if(l2 == NULL){ return l1; } ListNode* dummy = new ListNode(0); ListNode* head = dummy; while(l1 != NULL && l2 != NULL){ if(l1->val > l2->val){ head->next = l2; l2 = l2->next; } else{ head->next = l1; l1 = l1->next; } head = head->next; } if(l1 == NULL){ head ->next = l2; } if(l2 == NULL){ head->next = l1; } return dummy->next; } ListNode* sortList(ListNode* head) { if(head == NULL || head ->next == NULL){ return head; } ListNode* middle = findMiddle(head); ListNode* right = sortList(middle->next); middle -> next = NULL; ListNode* left = sortList(head); return mergeTwoLists(left, right); } };