148. Sort List

443 查看

题目:
Sort a linked list in O(n log n) time using constant space complexity.

解答:
(对于discuss中第二个最优解的解释)
根据时间复杂度的要求,很容易想到应该用merge sort的方法来做,那么就有两个步骤,分和法。先把整个list分成两部分,这里可以用找中间值的方法,在找中间值的同时,标记一下中间值的前一个node,也就是第一个list的最后一个node,然后找到中间值之前,将最后一个node的下一位标记为null,就成功地将这个list分成了两部分;接下来是merge, 那就建一个新的list,将两个sort好的list按最小数的大小依次放进新list中,最后返回merge的list。解法如下:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode sortList(ListNode head) {
        if (head == null || head.next == null) return head;
        
        //seperate the list into two parts
        //Track the last node of first list and point the end to null
        ListNode prev = null;
        ListNode slow = head, fast = head;
        while (fast != null && fast.next != null) {
            prev = slow;
            slow = slow.next;
            fast = fast.next.next;
        }
        prev.next = null;
        ListNode l1 = sortList(head);
        ListNode l2 = sortList(slow);
        
        return merge(l1, l2);
    }
    
    public ListNode merge(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode l = dummy;
        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                l.next = l1;
                l1 = l1.next;
            } else {
                l.next = l2;
                l2 = l2.next;
            }
            l = l.next;
        }
        
        while (l1 != null) {
            l.next = l1;
            l1 = l1.next;
            l = l.next;
        }
        while (l2 != null) {
            l.next = l2;
            l2 = l2.next;
            l = l.next;
        }
        
        return dummy.next;
    }
}