算法:链表最快的排序方法,分而治之再合并排序

题目

148. Sort List

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)?

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: []

Constraints:

The number of nodes in the list is in the range [0, 5 * 104].

-105 <= Node.val <= 105

解题思路

如果是数组,时间复杂度解法O(n logn) 比较多的选择,比如快速排序、分而治之再合并排序、堆排序等。但是在链表的世界里,只有分而治之的方法才是最快的。步骤如下:

  1. 找出中间节点,用单步和双步两个指针可以快速找出,并拆分为左边链表,右边链表;
  2. 递归调用继续拆分左边链表和右边链表,直到只有null或者只有一个节点为止;
  3. 逐个合并节点:定义结果空链表,对比合并的两个链表,小的值逐个拼接到结果链表中。

这种接法有个弊端,因为是递归,也就是会有栈溢出的风险。可以加个计数器,如果深度大于10,000 则抛出异常处理。

# Definition for singly-linked list.
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
class SortList:
    def sortList(self, head: ListNode) -> ListNode:
        if head == None or head.next == None:
            return head
        mid = self.getMid(head)
        left = self.sortList(head)
        right = self.sortList(mid)
        return self.merge(left, right)

    def merge(self, left: ListNode, right: ListNode) -> ListNode:
        result = ListNode()
        dummy = result
        while left and right:
            if left.val < right.val:
                dummy.next = left
                left = left.next
            else:
                dummy.next = right
                right = right.next
            dummy = dummy.next

        if left:
            dummy.next = left

        if right:
            dummy.next = right

        return result.next

    def getMid(self, head: ListNode) -> ListNode:
        oneStep = None
        while head and head.next:
            if oneStep == None:
                oneStep = head
            else:
                oneStep = oneStep.next
            head = head.next.next

        oneStepNext = oneStep.next
        oneStep.next = None

        return oneStepNext

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值