Sort List
Problem:
Sort a linked list in O(n log n) time using constant space complexity.
分析:
归并排序在数组上操作,归并时需要O(n)的空间,但链表中归并却容易,直接修改指针。分割的操作,利用两个指针,一个一次走一步,一个一次走两步,当走得快的走到末尾时,走得慢的恰好走到中间,这时,就将链表一分为二。递归对划分的两个链表再次分割,直到分割的链表中只有少于等于一个节点,可以直接返回。归并的过程相对容易,不需要额外申请空间与拷贝数据,全是指针操作。
1 class Solution { 2 public: 3 ListNode *sortList(ListNode *head) { 4 // split list into two parts 5 if(head == NULL || head->next == NULL) 6 return head; 7 8 ListNode *slow, *fast; 9 slow = fast = head; 10 while(fast->next != NULL && fast->next->next != NULL) { 11 slow = slow->next; 12 fast = fast->next; 13 fast = fast->next; 14 } 15 16 ListNode *list1, *list2; 17 list1 = head; 18 list2 = slow->next; 19 slow->next = NULL; 20 21 list1 = sortList(list1); 22 list2 = sortList(list2); 23 24 // merge two lists 25 ListNode *tail = NULL; 26 head = NULL; 27 while(list1 != NULL && list2 != NULL) { 28 if(list1->val < list2->val) { 29 if(head == NULL) { 30 head = tail = list1; 31 } else { 32 tail->next = list1; 33 tail = tail->next; 34 } 35 list1 = list1->next; 36 } else { 37 if(head == NULL) { 38 head = tail = list2; 39 } else { 40 tail->next = list2; 41 tail = tail->next; 42 } 43 list2 = list2->next; 44 } 45 } 46 47 if(list1 != NULL) { 48 tail->next = list1; 49 } 50 51 if(list2 != NULL) { 52 tail->next = list2; 53 } 54 55 return head; 56 } 57 };