[leetcode] 134 Sort List (链表 & 归并排序)

原创 2015年11月17日 22:55:07

首先看到题目中要求时间复杂度 O(n log n),时间复杂度为常数的时候,先将最容易实现的插入排序排除(O(n^2));接着想到快速排序和归并排序,

但是快速排序的最坏时间复杂度也为O(n^2),想了一会并且感觉也不是很好实现的样子。最后瞅了一眼discuss的代码,发现用的是归并排序,理论上归并排序的空间复杂度是线性的,也就是O(N),并不是常数,这点就需要结合链表的特性,只需要修改指针之间的关系就可以了,并不需要额外的空间开销,只需要new一个新的链表头即可。

由此分析,采用结合链表特性的归并排序是最好的方法。

我们使用归并排序时,先递归分解,每次分成两半,这里就需要用到追及法,也就是一个指针走2步,一个走一步,快的到末尾时,慢的正好到中间。

然后再使用merge函数由底至上归并为有序链表。具体看代码吧,注释很详细。

//归并排序(链表) 
class Solution {
public:
    ListNode* sortList(ListNode* head) {
    	if(head==NULL||head->next==NULL) //处理0个或1个的情况 
    	return head;
        return mergeSort(head);  //因为要递归本身,所以另写一个函数 
    }
    
    ListNode* mergeSort(ListNode* head)  //递归分解  
    {
       if(head==NULL||head->next==NULL)
       return head;
       
       //追及法求中点 
       ListNode* p=head;
       ListNode* q=head;
	   ListNode* p_pre=NULL;
	   while(q!=NULL&&q->next!=NULL)
	   {
   	      q=q->next->next;
		  p_pre=p;  //保存前半段的最后一个元素 
		  p=p->next;	
   	   } 
   	   p_pre->next=NULL;
	   ListNode* left=mergeSort(head);  //递归前半段 
	   ListNode* right=mergeSort(p);   //递归后半段
	   
	   return merge_top(left,right); 
    }
    
    ListNode* merge_top(ListNode* left,ListNode*right) //对有序的进行归并 
    {
    	ListNode* temp=new ListNode(0);
    	ListNode* cur=temp; 
    	while(left!=NULL&&right!=NULL)
    	{
	    	if(left->val<=right->val)
	    	{
	    		cur->next=left;//只需修改指针指向,无需开辟新的空间 
	    		left=left->next;
	    	}
	    	else
            {
	    	    cur->next=right;
				right=right->next;	
	    	}
	    	cur=cur->next;
    	}
	    	if(left!=NULL)
	    	cur->next=left;
	    	else if(right!=NULL)
	    	cur->next=right;
	    	else
	    	cur->next=NULL;
	    	
	    	cur=temp->next;  //返回第一个有内容的链表头部 
	    	
			delete temp;
			return cur; 
	    }
};


版权声明:本文为博主原创文章,未经博主允许不得转载。

【leetcode 单链表归并排序】Sort List

1、题目 2、分析 3、归并排序代码 4、快速排序代码
  • u012162613
  • u012162613
  • 2014年11月09日 22:13
  • 1562

[LeetCode] Merge Sorted Array 归并排序数组

Given two sorted integer arrays A and B, merge B into A as one sorted array. Note: You may assume th...
  • jiyanfeng1
  • jiyanfeng1
  • 2014年12月08日 05:52
  • 637

链表和归并排序(Merge Sort)

归并排序适合于对链表进行原址排序,即只改变指针的连接方式,不交换链表结点的内容。 归并排序的基本思想是分治法:先把一个链表分割成只有一个节点的链表,然后按照一定顺序、自底向上合并相邻的两个链表。 ...
  • Dread_naught
  • Dread_naught
  • 2014年12月12日 11:01
  • 1045

Leetcode Sort List 链表归并排序

本题好像使用quicksort是不能AC的,只能使用归并排序了。 之前觉得是很困难的题目。 训练了这么久算法,功力终于上升了。虽然还没达化境,但是以前觉得什么归并排序,快速排序好像很难,曾经死记过,始...
  • kenden23
  • kenden23
  • 2014年01月25日 09:38
  • 1967

LeetCode Sort List 解题报告

Sort a linked list in O(n log n) time using constant space complexity. http://oj.leetcode.com/proble...
  • worldwindjp
  • worldwindjp
  • 2014年02月08日 15:31
  • 8979

leetcode 134: Sort List

Sort List Total Accepted: 453 Total Submissions: 2621 Sort a linked list in O(n log n) time using...
  • xudli
  • xudli
  • 2013年11月19日 10:30
  • 2258

LeetCode(148)Sort List

题目如下: Sort a linked list in O(n log n) time using constant space complexity. 分析如下: 能够有O(n lgn)时间复杂度...
  • feliciafay
  • feliciafay
  • 2014年02月04日 08:09
  • 4393

Java单链表归并排序

概念归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,归并排序将两个已排序的表合并成一个表。归并排序基本原理通过对若干个有...
  • bug_moving
  • bug_moving
  • 2017年02月24日 08:53
  • 1283

Sort List 归并排序链表

Sort List   Sort a linked list in O(n log n) time using constant space complexity. /** * Definit...
  • u012605629
  • u012605629
  • 2015年05月28日 11:41
  • 259

[STL] List 中sort为什么采用归并排序

这几天在看STL(SGI版本----侯捷),在看完第一章后有点懵,但还是很震撼,STL的设计理念确实很好,至于有多么好我们都懂,所以就不再评价了。      由于刚刚开始看,所以有些东西并不是很透彻,...
  • zr1076311296
  • zr1076311296
  • 2016年05月22日 19:07
  • 802
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[leetcode] 134 Sort List (链表 & 归并排序)
举报原因:
原因补充:

(最多只允许输入30个字)