1. 程式人生 > >LeetCode—148. Sort List

LeetCode—148. Sort List

LeetCode—148. Sort List

題目

要求將連結串列按需排列。對時間和空間有要求。
在這裡插入圖片描述

思路及解法

因為有時間和空間限制增加了難度。 n l o g n nlogn

的內平均時間複雜度排序演算法只有三種,堆排序,快速排序和歸併排序,但快速排序的最壞情況是 n 2 n^2 ,不能用。堆排序和歸併排序的所有情況都是 n l
o g n nlogn
。對於歸併排序,我們知道需要 n n 的空間複雜度,即需要一個臨時陣列來存放排好序的元素,顯然也合理,但那是針對的是陣列,對於連結串列,歸併排序的空間複雜度為in-place 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) {
        if(head==null || head.next==null) return head;
        ListNode mid = getMiddleNode(head);
        ListNode rightList = mid.next;
        ListNode leftList = head;
        mid.next = null;
        return mergeList(sortList(leftList), sortList(rightList));
    }
    public ListNode mergeList(ListNode list1, ListNode list2){
        ListNode dummy = new ListNode(0);
        ListNode curr = dummy;
        while(list1!=null && list2!=null){
            if(list1.val<list2.val){
                curr.next = list1;
                list1 = list1.next;
            }else{
                curr.next = list2;
                list2 = list2.next;
            }
            curr = curr.next;
        }
        curr.next = list1!=null ? list1 : list2;
        return dummy.next;
    }
    public ListNode getMiddleNode(ListNode head){
        ListNode slow = head, fast = head;
        while(fast.next!=null && fast.next.next!=null){
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }
}