Sort a linked list in O(n log n) time using constant space complexity.
时间复杂度为O(nlogn),可以想到归并排序、快排、桶排序。
思路:使用归并排序,整体可以分为两体,一、构造两个已排序的子链表;二、将子链表合并。针对第一部分,可以使用快慢指针的方法,分割链表,然后对结点进行递归排序;针对第二部分,取出两子链表的表头结点进行比较大小,小的先放入新链表。针对后面大神们的删除newList的技巧,可以认真的学习。代码如下
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode *sortList(ListNode *head) 12 { 13 if(head==NULL||head->next==NULL) 14 return head; 15 return mergeTwo(head); 16 } 17 18 ListNode *mergeTwo(ListNode *head) 19 { 20 if(head==NULL|| head->next==NULL) 21 return head; 22 ListNode *preSlow=NULL; 23 ListNode *slow=head,*fast=head; 24 25 while(fast&&fast->next) 26 { 27 preSlow=slow; 28 slow=slow->next; 29 fast=fast->next->next; 30 } 31 preSlow->next=NULL; 32 ListNode *left=mergeTwo(head); 33 ListNode *right=mergeTwo(slow); 34 return megerTwoLists(left,right); 35 } 36 37 ListNode *megerTwoLists(ListNode *left,ListNode *right) 38 { 39 ListNode *newList=new ListNode(-1); 40 41 ListNode *pre=newList; 42 while(left&&right) 43 { 44 if(left->val > right->val) 45 { 46 pre->next=right; 47 right=right->next; 48 } 49 else 50 { 51 pre->next=left; 52 left=left->next; 53 } 54 pre=pre->next; 55 } 56 if(left) 57 pre->next=left; 58 else 59 pre->next=right; 60 61 //下面是大神们的写法。也可以直接写成return newList->next;但会造成内存泄漏? 62 slow=newList->next; 63 newList->next=NULL; 64 delete newList; 65 66 return slow; 67 } 68 };