Leecode 148. Sort List

Description: Given the head of a linked list, return the list after sorting it in ascending order.

Follow up: Can you sort the linked list in O(n logn) time and O(1) memory (i.e. constant space)?

Link: 148. Sort List

Examples:

Example 1:
Input: head = [4,2,1,3]
Output: [1,2,3,4]

Example 2:
Input: head = [-1,5,3,4,0]
Output: [-1,0,3,4,5]

Example 3:
Input: head = []
Output: []

思路: 我们比较熟悉数组的排序,那么我们就先保存链表的值到arr, 用归并排序对数组arr实现排序,然后在将排好的数值赋值到链表。

class Solution(object):
    def sortList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head or not head.next: return head
        p = head
        arr = []
        while p:
            arr.append(p.val)
            p = p.next
        new = self.merge_sort(arr)
        p = head
        while new:
            p.val = new.pop(0)
            p = p.next
        return head
            
    def merge_sort(self, arr):
        if len(arr) == 1:
            return arr
        mid = len(arr) // 2
        left = arr[:mid]
        right = arr[mid:]
        return self.merge(self.merge_sort(left), self.merge_sort(right))
    
    def merge(self, left, right):
        result = []
        while len(left) > 0 and len(right) > 0:
            if left[0] <= right[0]:
                result.append(left.pop(0))
            else:
                result.append(right.pop(0))
        result += left
        result += right
        return result

虽然归并排序的时间复杂度是符合的,但是我们两次遍历链表,并保存arr,时间和空间的浪费很大,现在来改一改。把对arr的操作改成对链表的,那么最重要的就是找到arr中的mid,链表怎么找?快慢指针,快指针每次走两步,慢指针走一步,当快指针走到结尾的之后,慢指针刚好在中间。

class Solution(object):
    def sortList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head or not head.next: return head
        pre, slow, fast = head, head, head
        while fast and fast.next:
            pre = slow
            slow = slow.next
            fast = fast.next.next
        pre.next = None
        left = self.sortList(head)
        right = self.sortList(slow)
        return self.merge(left, right)
    
    def merge(self, left, right):
        head = ListNode(0)
        move = head
        while left and right:
            if left.val <= right.val:
                move.next = left
                left = left.next
            else:
                move.next = right
                right = right.next
            move = move.next
        move.next = left if left else right
        return head.next

日期: 2021-03-30  Today present at reading group, seems good.

原文地址:https://www.cnblogs.com/wangyuxia/p/14597887.html