考察归并排序,快慢指针得中间节点
先切割,分治,然后合并排序
O(n log n) 时间复杂度,常数级空间复杂度
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode sortList(ListNode head) {
if (head == null || head.next == null)
return head;
// split the list into two halfs
ListNode left = head;
ListNode right = getMid(head);
ListNode tmp = right.next;
right.next = null;
right = tmp;
// 分治
left = sortList(left);
right = sortList(right);
// 合并
return merge(left, right);
}
// 用快慢指针算法来得到链表的中点
private ListNode getMid(ListNode head) {
ListNode slow = head, fast = head.next;
while(fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
// 合并
private ListNode merge(ListNode list1 , ListNode list2) {
ListNode tail = new ListNode(), dummy = tail;
while(list1 != null && list2 != null) {
if(list1.val < list2.val) {
tail.next = list1;
list1 = list1.next;
}
else {
tail.next = list2;
list2 = list2.next;
}
tail = tail.next;
}
if (list1 != null)
tail.next = list1; // 已经有序,直接尾插整个list1即可
if (list2 != null)
tail.next = list2;
return dummy.next;
}
}