使用合并排序在O(n log n)时间内对链表进行排序

时间:2014-08-18 01:57:59

标签: python algorithm sorting mergesort

这实际上是Leetcode的算法实践。以下是我的代码:

class ListNode:
    def __init__(self, x, next=None):
        self.val = x
        self.next = next

class Solution:
    # @param head, a ListNode
    # @return a ListNode
    def sortList(self, head):
        if head is None or head.next is None:
            return head
        first, second = self.divide_list(head)
        self.sortList(first)
        self.sortList(second)
        return self.merge_sort(first, second)

    def merge_sort(self, first, second):
        if first is None:
            return second
        if second is None:
            return first
        left, right = first, second
        if left.val <= right.val:
            current, head = left, first
            left = left.next
        else:
            current, head = right, second
            right = right.next
        while left and right:
            if left.val <= right.val:
                current.next = left
                left = left.next
            else:
                current.next = right
                right = right.next
            current = current.next

        if left is not None:
            current.next = left
        if right is not None:
            current.next = right
        return head

    def divide_list(self, head):
        fast, slow = head.next, head
        while fast.next:
            slow = slow.next
            fast = fast.next
            if fast.next:
                fast = fast.next
        second_part = slow.next
        slow.next = None
        return head, second_part

这个想法很简单,只是Merge Sort的基本概念。但结果似乎不正确,运行时间太长,无法通过Leetcode的判断(Time Limit Exceeded,但为什么不是O(nlog(n))?)。以下是我的测试代码:

基础测试:

c= ListNode(3, ListNode(1, ListNode(2, ListNode(4))))
result =Solution().sortList(c)
while result:
    print result.val
    result = result.next # result: 2, 3, 4 which missing 1

有人有想过优化这段代码吗?

1 个答案:

答案 0 :(得分:2)

违规行是

        self.sortList(first)
        self.sortList(second)

问题是列表头可能在排序后发生变化。修复是

        first = self.sortList(first)
        second = self.sortList(second)

作为一般提示,我建议您使用sentinel nodes来减少特殊情况的数量。