要求时间为O(nlogn),最适合就是merge sort,每次从n/2处断开,对两段递归sort,然后再merge起来。
空间是O(logn)用了栈空间
package Level4;
import Utility.ListNode;
/**
* Sort List
*
* Sort a linked list in O(n log n) time using constant space complexity.
*
*/
public class S144 {
public static void main(String[] args) {
int[] list = {1,4,2,3};
ListNode head = ListNode.create(list);
ListNode h = sortList(head);
h.print();
}
public static ListNode sortList(ListNode head) {
if(head==null || head.next==null){ // 链表没有元素或是只有一个元素的情况直接返回
return head;
}
ListNode fast = head;
ListNode slow = head;
ListNode preSlow = head;
// 找到中间节点的前一个
while(fast!=null && fast.next!=null){
fast = fast.next.next;
preSlow = slow;
slow = slow.next;
}
// System.out.println(preSlow.val);
// 断开,分成两段
preSlow.next = null;
ListNode first = sortList(head); // 得到以排序好的前半段
ListNode second = sortList(slow); // 得到以排序好的后半段
ListNode dummy = new ListNode(-1);
ListNode dummyCur = dummy;
while(first!=null && second!=null){ // 合并两半段
if(first.val<second.val){
dummyCur.next = first;
first = first.next;
}else if(second.val<=first.val){
dummyCur.next = second;
second = second.next;
}
dummyCur = dummyCur.next;
}
while(first != null){
dummyCur.next = first;
first = first.next;
dummyCur = dummyCur.next;
}
while(second != null){
dummyCur.next = second;
second = second.next;
dummyCur = dummyCur.next;
}
return dummy.next;
}
}
Merge Sort:
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public static ListNode sortList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode slow = head, fast = head, preSlow = head;
while (fast != null && fast.next != null) {
preSlow = slow;
slow = slow.next;
fast = fast.next.next;
}
preSlow.next = null;
ListNode h1 = sortList(head);
ListNode h2 = sortList(slow);
return mergeList(h1, h2);
}
public static ListNode mergeList(ListNode h1, ListNode h2) {
ListNode dummyHead = new ListNode(0);
ListNode dummy = dummyHead;
while (h1 != null && h2 != null) {
if (h1.val <= h2.val) {
dummy.next = h1;
h1 = h1.next;
} else {
dummy.next = h2;
h2 = h2.next;
}
dummy = dummy.next;
}
while (h1 != null) {
dummy.next = h1;
h1 = h1.next;
dummy = dummy.next;
}
while (h2 != null) {
dummy.next = h2;
h2 = h2.next;
dummy = dummy.next;
}
return dummyHead.next;
}
}