[LeetCode] 148. Sort List Java

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

题意及分析:要求使用o(nlogn)的时间复杂度和o(1)的空间复杂度将链表排序。o(nlogn)的排序算法有快速排序,归并排序和堆排序。但是快速排序最差情况下时间复杂度为o(n^2),所以不考虑,堆排序比较复杂,因此我这里使用归并排序。对于一个数组来说,归并排序主要是讲数组从中间分割成两部分,然后对左右子数组做同样操作,直至每个子数组都只有一个元素,然后两两合并。因为这里是链表,所以怎么找到中间分割点比较关键,这里使用两个指针slow,fast,slow每次移动一步,fast每次移动两步,当fast到链表尾时,slow所在位置就是链表中。我这里使用的是递归的方法求解。对于链表来说,非递归算法效率更高,所以合并处可以使用非递归算法,这样会快很多。

代码:

递归:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode sortList(ListNode head) {
		 if(head==null||head.next==null) return head;
		 
		 ListNode slow=head;
		 ListNode fast=head;
		 ListNode p=head;
		 
		 while(fast!=null&&fast.next!=null){		//slow每次走一步,fast每次走两步,当fast走到最后时,slow走到链表的中间,这样就可以将链表分成两半
			 p=slow;
			 slow=slow.next;
			 fast=fast.next.next;
		 }
		 p.next=null;		//将前半段链表设置为null结尾,这样链表就被分成(head,p),(slow,fast)
		 
		 ListNode h1=sortList(head);
		 ListNode h2=sortList(slow);
		 
		 return mergeList(h1, h2);
	 }
		 
	 public ListNode mergeList(ListNode h1,ListNode h2){		//合并两个链表
		if(h1==null) return h2;
		if(h2==null) return h1;
		if(h1.val<h2.val){
			h1.next=mergeList(h1.next, h2);
			return h1;
		}else{
			h2.next=mergeList(h1, h2.next);
			return h2;
		}
	 }
}

 非递归:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode sortList(ListNode head) {
		 if(head==null||head.next==null) return head;
		 
		 ListNode slow=head;
		 ListNode fast=head;
		 ListNode p=head;
		 
		 while(fast!=null&&fast.next!=null){		//slow每次走一步,fast每次走两步,当fast走到最后时,slow走到链表的中间,这样就可以将链表分成两半
			 p=slow;
			 slow=slow.next;
			 fast=fast.next.next;
		 }
		 p.next=null;		//将前半段链表设置为null结尾,这样链表就被分成(head,p),(slow,fast)
		 
		 ListNode h1=sortList(head);
		 ListNode h2=sortList(slow);
		 
		 return mergeList(h1, h2);
	 }
		 
	 public ListNode mergeList(ListNode h1,ListNode h2){		//合并两个链表
		if(h1==null) return h2;
		if(h2==null) return h1;
		ListNode res = new ListNode(0);		//结果链表
		ListNode x=res;
		while(h1!=null&&h2!=null){
			if(h1.val<h2.val){
				x.next=h1;
				h1=h1.next;
				x=x.next;
			}else{
				x.next=h2;
				h2=h2.next;
				x=x.next;
			}
		}
		if(h1!=null)
			x.next=h1;
		if(h2!=null)
			x.next=h2;
		
		return res.next;
	 }
}

 

  

 

  

 

 

  

 

posted @ 2017-06-29 10:06  荒野第一快递员  阅读(476)  评论(0编辑  收藏  举报