LeetCode python-148. 排序链表

LeetCode python-148. 排序链表

先看题目:

(题目来力扣网站)LeetCode python-148. 排序链表_第1张图片

思路:

因为时间复杂度是nlogn,所以采用二分法。假设是n = 2^k个输入,经过二分法,有 k = logn层。每一层排序的时间复杂度是n,故整体时间复杂度是nlogn。
方法一:
在 left, right = self.sortList(head), self.sortList(mid)之前实现二分法操作,分到最小单元,即left = None,right = None,之后实现排序操作,再合并,循环,直到head =None或head.next== None。

#归并排序,递归法。
#通过二分法得到最小节点单元,直到left.next = None and right.next = None.然后开始合并
class ListNode(object):
    def __init__(self, val, next=None):
        self.val = val
        self.next = next
class Solution:
    def sortList(self, head):
        if head == None or head.next == None:
            return head     # termination.
        slow, fast = head, head.next#快指针走的是慢指针的两倍,故慢指针可以找到中点。
        while fast and fast.next:
            fast, slow = fast.next.next, slow.next
        mid, slow.next = slow.next, None 
        left, right = self.sortList(head), self.sortList(mid)#递归操作
        h = res = ListNode(0)
        while left and right:
            if left.val < right.val:
                h.next = left
                left = left.next
            else:
                h.next = right
                right = right.next
            h = h.next
        h.next = left if left else right
        return res.next

方法二:
利用pre和pre.next不断存储更新链表。
定位h,找到h1,h2,比较二者大小,不断更新pre和pre.next,直到head= None。

#归并排序,自底部至顶部
#没有用到递归操作
class ListNode(object):
    def __init__(self, val, next=None):
        self.val = val
        self.next = next
class Solution:
    def sortList(self, head):
        h, length, intv = head, 0, 1 #统计出长度
        while h:
            h, length = h.next, length + 1# 分成最最小单元
        res = ListNode(0)
        res.next = head 
        while intv < length:
            pre, h = res, res.next
            while h:# h1, h2#当h存在时
                h1, i = h, intv #找到h1
                while i and h:
                    h, i = h.next, i - 1
                if i:
                    break ##当i不为0,但是head=None
                h2, i = h, intv #找到h2
                while i and h:
                    h, i = h.next, i - 1
                c1, c2 = intv, intv - i # c1和c2分别是h1和h2的单元长度。c2 的长度小于等于intv的长度。
                while c1 and c2: #排序
                    if h1.val < h2.val:
                        pre.next, h1, c1 = h1, h1.next, c1 - 1#反复比较h1 和 h2 ,当h1.next存在时,h1.next和h2继续比较
                    else:
                        pre.next, h2, c2 = h2, h2.next, c2 - 1
                    pre = pre.next
                pre.next = h1 if c1 else h2
                while c1 > 0 or c2 > 0:#找到下一次和h
                    pre, c1, c2 = pre.next, c1 - 1, c2 - 1
                pre.next = h
            intv *= 2
        return res.next

两个方法的实验结果,几乎一致。如下:
LeetCode python-148. 排序链表_第2张图片

收获:

反复debug,直到完全明白递归操作是怎么实现的。链表的排序因为有self.next=next,故直接变换其接下来的地址即可。
也可查看详细解释:
Sort List (归并排序链表)

你可能感兴趣的:(python,排序,LeetCode)