Sort List leetcode

Sort List

  Total Accepted: 16300  Total Submissions: 79978 My Submissions

Sort a linked list in O(n log n) time using constant space complexity.

Have you been asked this question in an interview? 

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;
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值