Sort a linked list in O(n log n) time using constant space complexity.
Discuss
归并排序的复杂度是O(nlog(n)),使用链表的话,可以用常数空间来完成排序。因为递归到底层之后,只需要交换节点。之前用C++写过一次,现在用java实现。看网上对于找到拆分点使用快慢指针的方法,我使用的是比较笨的计数方法。时间在时间复杂度上其实是一样的,一次走到底,并且再次走一半。而快慢指针则是同时一个走到底,一个走一半。快慢指针的代码要简短一些。
C++代码
/** 9:16 * At the first time, I think this is a very hard problem. Because, the sort function in Java api is referenced from a * paper, whose time complexity is O(n*log(n)). However, after my failture from works application, I realize that I must * think and think again, and imitate the progress of the algorithm. I think in this way, I can find the solution of some * problem by muself. * 9:20-> 9:56, about 40minutes to write this algorithm right, but the space may get some error. * I can sort in O(nlogn),but should use O(n) space * */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *sortList(ListNode *head) { int len = getLen(head); if(len<2) { return head; } ListNode *h = mergeSort(head,len); return h; } //complexity is O(len/2) +O(len) ListNode *mergeSort(ListNode *head,int len) { if(len>1) { int mid = len/2; ListNode *h1 = getKth(mid,head); ListNode *h2 = h1->next; h1->next = NULL; int len1 = mid; int len2 = len-mid; h1 = mergeSort(head,len1); h2 = mergeSort(h2,len2); return merge(h1,h2); }else { return head; } } ListNode *merge(ListNode *h1,ListNode *h2) { ListNode *h3 = NULL,*tmp=NULL,*before; if(h1->val<h2->val) { h3 = h1; before = h1; tmp = h1->next; h1->next = h2; h1 = tmp; }else { h3 = h2; tmp = h2->next; before = h2; h2->next = h1; h2 = tmp; } while(h1!=NULL && h2!=NULL) { if(h1->val<h2->val) { tmp = h1->next; before->next = h1; h1->next = h2; h1 = tmp; }else { tmp = h2->next; before->next = h2; h2->next = h1; h2 = tmp; } before = before->next; } return h3; } int getLen(ListNode *h) { int len = 0; while(h!=NULL) { h = h->next; len++; } return len; } ListNode * getKth(int k, ListNode *h) { int i = 1; while(i<k) { h = h->next; i++; } return h; } };
java代码:
class ListNode { int val; ListNode next; ListNode(int x) { val = x; next = null; } } public class Solution{ public static void main(String[] args) { ListNode res,h1,h2; res = h1 = new ListNode((int) (Math.random()*100)); Solution s = new Solution(); for(int i=0;i<10;i++){ h2 = new ListNode((int) (Math.random()*100)); h1.next = h2; h1 = h1.next; } res = s.sortList(res); while(res!=null){ System.out.println(res.val+"->"); res = res.next; } } public ListNode sortList(ListNode head){ int len = getLen(head); if(len<2) { return head; } return mergeSort(head,0,len-1); } ListNode mergeSort(ListNode head,int start,int end) { if(start<end) { int mid = (start + end)/2; int count = 0; ListNode next = head; while(count<mid) { next = next.next; count++;//忘记这个加法了 } ListNode nextH = next.next; next.next = null; head = mergeSort(head,start,mid); nextH = mergeSort(nextH,0,end-mid-1); head = merge(head,nextH); return head; }else { return head; } } ListNode merge(ListNode h1,ListNode h2) { ListNode newH; if(h1.val<h2.val) { newH = h1; h1 = h1.next; }else{ newH = h2; h2=h2.next; } ListNode res = newH; while(h1!=null &&h2!=null) { if(h1.val<h2.val) { newH.next = h1; h1 = h1.next; }else{ newH.next = h2; h2 = h2.next; } newH = newH.next; } if(h1!=null){ newH.next = h1; }else{ newH.next = h2; } return res; } int getLen(ListNode head){ int count = 0; while(head!=null){ head = head.next; count++; } return count; } }