Description
Sort a linked list in O(n log n) time using constant space complexity.
Solution
Merge sort
使用歸并排序思想做這道題還是蠻簡單的。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode sortList(ListNode head) {
return mergeSort(head);
}
public ListNode mergeSort(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode slow = head;
ListNode fast = head.next;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
ListNode head2 = slow.next;
slow.next = null;
head = mergeSort(head);
head2 = mergeSort(head2);
return mergeSortedList(head, head2);
}
public ListNode mergeSortedList(ListNode p, ListNode q) {
ListNode dummy = new ListNode(0);
ListNode tail = dummy;
while (p != null && q != null) {
if (p.val <= q.val) {
tail.next = p;
p = p.next;
} else {
tail.next = q;
q = q.next;
}
tail = tail.next;
}
if (p != null) {
tail.next = p;
} else {
tail.next = q;
}
return dummy.next;
}
}
Quick sort(TLE)
雖然會超時但是寫起來也蠻有意思的。pivot自然選擇head節點,比較tricky的地方是如何去移動節點。好實現的方式是將小于pivot的移動到當前鏈表的頭部,但注意需要一個prev節點記錄head之前的節點(防止鏈表被弄斷啊),然后將節點插入到prev和firstHead之間。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode sortList(ListNode head) {
return quickSort(null, head, null);
}
public ListNode quickSort(ListNode prev, ListNode head, ListNode tail) {
if (head == tail || head.next == tail) {
return head;
}
ListNode fhead = head;
ListNode curr = head;
// compare curr.next not curr so we could spare a pre pointer
while (curr.next != tail) {
if (curr.next.val < head.val) {
// move p to the between of prev and fhead
ListNode p = curr.next;
curr.next = p.next;
p.next = fhead;
if (prev != null) {
prev.next = p;
}
fhead = p;
} else {
curr = curr.next;
}
}
quickSort(head, head.next, tail);
return quickSort(prev, fhead, head);
}
}