Sort a linked list in O(n log n) time using constant space complexity.
- Difficulty: Medium
思路:對於數組元素排序時間複雜度爲O(nlogn)的方式有快速排序,歸併排序,堆排序。由於題目要求,空間複雜度爲常數階,考慮使用歸併排序來解決。
首先,定義一個快指針和一個慢指針,從鏈表的頭部開始,慢指針一次走一步,快指針一次走兩步。當快指針->next = null是 滿指針正好在鏈表中間,此時另滿指針->next = null;就將一個鏈表分成兩段。遞歸該操作。直到每一個鏈表都只有一個元素。然後再進行根據元素大小依次歸併。
例如: 3 -> 1 -> 4 -> 2
第一次: 3 -> 1 -> null 4 -> 2 -> null
第二次: 3 -> null 1-> null 4 -> null 2 -> null
歸併返回 : 1 -> 3 -> null 2 - > 4 -> null
歸併返回 : 1 -> 2 -> 3 -> 4 -> null
下面是具體實現源碼:
public class Solution {
public ListNode sortList(ListNode head) {
if (head == null || head.next == null)
return head;
// step 1. cut the list to two halves
ListNode prev = null, slow = head, fast = head;
while (fast != null && fast.next != null) {
prev = slow;
slow = slow.next;
fast = fast.next.next;
}
prev.next = null;
// step 2. sort each half
ListNode l1 = sortList(head);
ListNode l2 = sortList(slow);
// step 3. merge l1 and l2
return merge(l1, l2);
}
ListNode merge(ListNode l1, ListNode l2) {
ListNode l = new ListNode(0), p = l;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
p.next = l1;
l1 = l1.next;
} else {
p.next = l2;
l2 = l2.next;
}
p = p.next;
}
if (l1 != null)
p.next = l1;
if (l2 != null)
p.next = l2;
return l.next;
}
}