Sort a linked list in O(n log n) time using constant space complexity.
Use recursion: cut the list in half and merge the two half.
/**
* 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);
}
private ListNode mergeList(ListNode A, ListNode B) {
if (A == null && B == null) {
return null;
}
ListNode dummy = new ListNode(0);
dummy.next = A;
A = dummy;
while (A.next != null && B != null) {
if (A.next.val > B.val) {
ListNode p1 = A.next;
ListNode p2 = B;
B = B.next;
A.next = p2;
p2.next = p1;
}
A = A.next;
}
if (B != null) {
A.next = B;
}
return dummy.next;
}
private ListNode findMiddle(ListNode head) {
if (head == null) {
return null;
}
ListNode walker = head, runner = head;
while (runner.next != null && runner.next.next != null) {
runner = runner.next.next;
walker = walker.next;
}
return walker;
}
}