标签:
标题: | Sort List |
通过率: | 21.3% |
难度: | 中等 |
Sort a linked list in O(n log n) time using constant space complexity.
本题就是一个排序的问题,但是是针对单向链表去处理,那么问题关键就是怎么去处理链表,时间复杂度为nlogn,所以可以使用:
1、归并排序。
2、快速排序。
我分别实现了上述两种算法,
第一种:对于实现归并排序的关键就是如何找到链表的中间值和如何去合并两个链表,对于如何合并两个链表是比较简单的,用一个额外的链表每次都链接两个链表中值较小的那一个,但是对于如何找到中间值,我参考了网上的思路,用两个指针,一个指针每次走一步,一个指针每次走两步,当快指针走到头时,慢指针所处的位置就是中间值,下面看代码:
java代码:
1 /** 2 * Definition for singly-linked list. 3 * class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int x) { 7 * val = x; 8 * next = null; 9 * } 10 * } 11 */ 12 public class Solution { 13 public ListNode sortList(ListNode head) { 14 if(head==null||head.next==null)return head; 15 ListNode mid=getMid(head); 16 ListNode sec=mid.next; 17 mid.next=null; 18 return combineList(sortList(head),sortList(sec)); 19 } 20 public ListNode combineList(ListNode first,ListNode second){ 21 ListNode result=new ListNode(1); 22 ListNode tmp=result; 23 while(first!=null&&second!=null){ 24 if(first.val<second.val){ 25 tmp.next=first; 26 first=first.next; 27 } 28 else 29 { 30 tmp.next=second; 31 second=second.next; 32 } 33 tmp=tmp.next; 34 } 35 if(first!=null){ 36 tmp.next=first; 37 } 38 if(second!=null){ 39 tmp.next=second; 40 } 41 return result.next; 42 } 43 public ListNode getMid(ListNode head){ 44 ListNode p=head; 45 ListNode q=head; 46 while(q.next!=null&&q.next.next!=null){ 47 p=p.next; 48 q=q.next.next; 49 } 50 return p; 51 52 } 53 }
python代码:
1 class Solution: 2 def mergeTwoLists(self, l1, l2): 3 head = ListNode(0) 4 current = head 5 while l1 != None and l2 != None: 6 if l1.val <= l2.val: 7 current.next, current, l1 = l1, l1, l1.next 8 else: 9 current.next, current, l2 = l2, l2, l2.next 10 if l1 != None: 11 current.next = l1 12 if l2 != None: 13 current.next = l2 14 return head.next 15 16 def sortList(self, head): 17 if head == None or head.next == None: 18 return head 19 fast, slow, prev = head, head, None 20 while fast != None and fast.next != None: 21 prev, fast, slow = slow, fast.next.next, slow.next 22 prev.next = None 23 sorted_l1 = self.sortList(head) 24 sorted_l2 = self.sortList(slow) 25 return self.mergeTwoLists(sorted_l1, sorted_l2)
第二种是快排,快排的关键是扫描,但是单向链表不支持双向扫描,那么就需要用两个指针,一前一后从链表的开头开始扫描,当前指针的值小于key时,进行与后指针的值交换。
java代码如下:
1 /** 2 * Definition for singly-linked list. 3 * class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int x) { 7 * val = x; 8 * next = null; 9 * } 10 * } 11 */ 12 public class Solution { 13 public ListNode sortList(ListNode head) { 14 quickSort(head,null); 15 return head; 16 17 } 18 public void quickSort(ListNode start,ListNode end){ 19 if(start!=end){ 20 ListNode position=getPostion(start,end); 21 quickSort(start,position); 22 quickSort(position.next,end); 23 } 24 25 } 26 public ListNode getPostion(ListNode start,ListNode end){ 27 ListNode p=start; 28 int key=p.val; 29 ListNode q=p.next; 30 int tmp=0; 31 while(q!=end){ 32 if(q.val<key){ 33 p=p.next; 34 tmp=p.val; 35 p.val=q.val; 36 q.val=tmp; 37 } 38 q=q.next; 39 } 40 tmp=start.val; 41 start.val=p.val; 42 p.val=tmp; 43 return p; 44 } 45 }
标签:
原文地址:http://www.cnblogs.com/pkuYang/p/4293851.html