Sort a linked list in O(n log n) time using constant space complexity.
归并排序的复杂度是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;
}
}