自顶向下(递归)
class Solution {
public ListNode sortList(ListNode head) {
return sortList(head, null);
}
public ListNode sortList(ListNode head, ListNode tail){
/**
* 自定向下,归并排序
* 递归终止条件,链表节点数小于2
* 但是不能用head.next == null来判断只有一个节点,因为中间部分的元素next都不为null
* 而每个小区间的链表都要是独立的,便于后面的merge合并,因此head还要指向null
*/
if (head == null){
return head;
}
if (head.next == tail){
head.next = null;
return head;
}
/**
* 使用快慢指针找出链表中间节点
* 快指针每次移动2步,慢指针每次移动1步,当快指针到达链表末尾时,慢指针指向的链表节点即为链表的中点
*/
ListNode fast = head;
ListNode slow = head;
while (fast != tail){
fast = fast.next;
slow = slow.next;
if (fast != tail){
fast = fast.next;
}
}
/**
* 尾指针是不包括的,因此list2从mid开始而不是mid.next
*/
ListNode mid = slow;
ListNode list1 = sortList(head, mid);
ListNode list2 = sortList(mid, tail);
return merge(list1, list2);
}
public ListNode merge(ListNode list1, ListNode list2){
ListNode dummyHead = new ListNode();
ListNode cur = dummyHead;
ListNode cur1 = list1;
ListNode cur2 = list2;
while (cur1 != null && cur2 != null){
if (cur1.val <= cur2.val){
cur.next = cur1;
cur1 = cur1.next;
cur = cur.next;
}
else {
cur.next = cur2;
cur2 = cur2.next;
cur = cur.next;
}
}
if (cur1 != null){
cur.next = cur1;
}
if (cur2 != null){
cur.next = cur2;
}
return dummyHead.next;
}
}
/**
* 时间复杂度 O(nlogn)
* 空间复杂度 O(logn)
*/
自底向上
class Solution {
public ListNode sortList(ListNode head) {
if (head == null || head.next == null){
return head;
}
int length = 0;
ListNode cur = head;
/**
* 遍历链表,获取长度
*/
while (cur != null){
length++;
cur = cur.next;
}
ListNode dummyHead = new ListNode(0, head);
/**
* 第一层循环,小区间长度size从1开始,每次翻倍
*/
for (int size = 1; size < length; size *= 2) {
ListNode prev = dummyHead;
ListNode curr = dummyHead.next;
/**
* 第二层循环,从第一个节点开始,每次遍历邻近的两个长度为size的小区间
* 找到这两个小区间的头节点,不要忘记尾节点都要指向null
*/
while (curr != null){
ListNode list1 = curr;
/**
* 找到第一个区间的尾节点curr
*/
for (int i = 1; i < size && curr.next != null; i++) {
curr = curr.next;
}
/**
* 第二个区间的头节点就是curr.next
*/
ListNode list2 = curr.next;
curr.next = null;
curr = list2;
/**
* 此处curr可能为null,需要判断一下
*/
for (int i = 1; i < size && curr != null && curr.next != null; i++) {
curr = curr.next;
}
ListNode next = null;
/**
* 因为curr可能为null,所以要单独判断
*/
if (curr != null){
next = curr.next;
curr.next = null;
}
/**
* 将这两个区间合并后,放在prev后,然后prev后移到第二个区间的尾节点
*/
prev.next = merge(list1, list2);
while (prev.next != null){
prev = prev.next;
}
curr = next;
}
}
return dummyHead.next;
}
public ListNode merge(ListNode list1, ListNode list2){
ListNode dummyHead = new ListNode();
ListNode cur = dummyHead;
while (list1 != null && list2 !=null){
if (list1.val <= list2.val){
cur.next = list1;
list1 = list1.next;
}
else {
cur.next = list2;
list2 = list2.next;
}
cur = cur.next;
}
cur.next = list1 == null ? list2 : list1;
return dummyHead.next;
}
}
/**
* 时间复杂度 O(nlogn)
* 空间复杂度 O(1)
*/
https://leetcode-cn.com/problems/sort-list/