题目
leetcode 148. 排序链表
解法一:自顶向下归并排序
class Solution {
public ListNode sortList(ListNode head) {
return mergeSort(head, null);
}
private ListNode mergeSort(ListNode head, ListNode tail) {
if (head == null) return null;
if (head.next == tail) {
head.next = null;
return head;
}
ListNode slow = head, fast = head;
while (fast != tail) {
slow = slow.next;
fast = fast.next;
if (fast != tail) fast = fast.next;
}
ListNode mid = slow;
ListNode newHead1 = mergeSort(head, mid);
ListNode newHead2 = mergeSort(mid, tail);
ListNode merged = merge(newHead1, newHead2);
return merged;
}
private ListNode merge(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(), p = dummyHead, p1 = l1, p2 = l2;
while (p1 != null && p2 != null) {
if (p1.val < p2.val) {
p.next = p1;
p = p.next;
p1 = p1.next;
} else {
p.next = p2;
p = p.next;
p2 = p2.next;
}
}
if (p1 != null) p.next = p1;
if (p2 != null) p.next = p2;
return dummyHead.next;
}
}
- 时间复杂度:O(nlogn)
- 空间复杂度:O(logn)
解法二:自底向上归并排序
class Solution {
public ListNode sortList(ListNode head) {
if (head == null) return null;
int length = 0;
ListNode p = head;
while (p != null) {
length++;
p = p.next;
}
ListNode dummyHead = new ListNode(0, head);
for (int subLength = 1; subLength < length; subLength <<= 1) {
ListNode prev = dummyHead, curr = dummyHead.next;
while (curr != null) {
ListNode head1 = curr;
for (int i = 1; i < subLength && curr != null && curr.next != null; i++) curr = curr.next;
ListNode head2 = curr.next;
curr.next = null;
curr = head2;
for (int i = 1; i < subLength && curr != null && curr.next != null; i++) curr = curr.next;
ListNode next = null;
if (curr != null) {
next = curr.next;
curr.next = null;
}
ListNode merged = merge(head1, head2);
prev.next = merged;
while (prev.next != null) prev = prev.next;
curr = next;
}
}
return dummyHead.next;
}
private ListNode merge(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(), p = dummyHead, p1 = l1, p2 = l2;
while (p1 != null && p2 != null) {
if (p1.val < p2.val) {
p.next = p1;
p = p.next;
p1 = p1.next;
} else {
p.next = p2;
p = p.next;
p2 = p2.next;
}
}
if (p1 != null) p.next = p1;
if (p2 != null) p.next = p2;
return dummyHead.next;
}
}