在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
示例 1:
输入: 4->2->1->3 输出: 1->2->3->4
示例 2:
输入: -1->5->3->4->0 输出: -1->0->3->4->5
/*
思路:看到O(n log n) 首先想到的是递归,排序中的归并递归排序满足这个时间复杂度
难点一:找到一个连表的中间节点
难点二: 两个连表进行合并
*/
public ListNode sortList(ListNode head) {
if (head == null) return null;
return mergeSort(head);
}
/*
此方法是把一个连表分成两个后最后调用合并方法进行合并返回一个连表
*/
public ListNode mergeSort(ListNode head) {
if (head.next == null) {
return head;
}
//找到中间节点的方法可以是两个指针一个速度是1一个速度是2当快指针走到末尾是慢指针则为中间节点
//快
ListNode f = head;
//慢
ListNode l = head;
//中间节点
ListNode mid = null;
while (f != null && f.next != null) {
mid = l;
l = l.next;
f = f.next.next;
}
mid.next = null;
ListNode left = mergeSort(head);
//因为最后一次会继续向后在走一次到达中间节点的下一个
ListNode right = mergeSort(l);
//此函是为合并连表
return merge(left, right);
}
public ListNode merge(ListNode left, ListNode right) {
//用于返回用的头
ListNode heard = new ListNode(0);
//遍历的指针
ListNode index = heard;
while (left != null && right != null) {
// 取小
if (left.val > right.val) {
index.next = right;
index = index.next;
right = right.next;
} else {
index.next = left;
index = index.next;
left = left.next;
}
}
if (left != null) {
index.next = left;
}
if (right != null) {
index.next = right;
}
return heard.next;
}