题目:
Sort a linked list in O(n log n) time using constant space complexity.
分析:
在排序算法中,时间复杂度为O(n log n)的算法有快速排序,归并排序和堆排序。但由于链表的归并排序时间复杂度为O(1),所以在这里选用归并排序。
归并排序的思想是将链表不断的一分为二,然后进行排序,最后将一分为二的链表融合起来得到排序后的链表。具体分为三个步骤,一是找到链表中间的
节点,二是分别对两个部分的链表进行归并排序,三是将排序后的两个部分的链表进行融合。因此代码如下:
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode sortList(ListNode head) {
if (head == null || head.next == null)
return head;
ListNode mid = findMiddle(head);
ListNode right = sortList(mid.next);
mid.next = null;
ListNode left = sortList(head);
return mergeList(left,right);
}
public ListNode findMiddle(ListNode head){
ListNode pre = head;
ListNode aft = head.next;
while(aft != null && aft.next != null){
pre = pre.next;
aft = aft.next.next;
}
return pre;
}
public ListNode mergeList(ListNode l1, ListNode l2){
if (l1 == null)
return l2;
if (l2 == null)
return l1;
ListNode head = new ListNode(0);
ListNode tmp = head;
while (l1 != null && l2 != null){
if (l1.val < l2.val){
tmp.next = l1;
l1 = l1.next;
}
else{
tmp.next = l2;
l2 = l2.next;
}
tmp = tmp.next;
}
if (l1 == null)
tmp.next = l2;
if (l2 == null)
tmp.next = l1;
return head.next;
}
}