Leetcode 148. Sort List python

这篇博客介绍了如何在O(n log n)的时间复杂度和O(1)的空间复杂度下对链表进行排序。首先讨论了使用最小堆的方法,虽然时间效率高但不满足空间复杂度要求。接着详细阐述了归并排序的思想,通过双指针技巧将链表分为两部分,并在链表本身上进行排序,从而达到题目要求的空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

Sort a linked list in O(n log n) time using constant space complexity.
Example 1:
Input: 4->2->1->3
Output: 1->2->3->4
Example 2:
Input: -1->5->3->4->0
Output: -1->0->3->4->5

解法1:利用最小堆

循环一次整个链表,将node的值存入一个最小堆中,再循环这个最小堆,将元素一次pop出来,构建新链表

class Solution(object):
    def sortList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head:
            return None
        l = []
        while head:
            heapq.heappush(l,head.val)
            head = head.next
        first_val = heapq.heappop(l)
        first = ListNode(first_val)
        tmp = first
        while l:
            curr_val = heapq.heappop(l)
            tmp.next = ListNode(curr_val)
            tmp = tmp.next
        return first

时间复杂度:O(Nlog(N))
空间复杂度:O(N),需要构建一个最小堆

解法2:利用归并排序的思想

题目要求的是constant space,换句话说就是O(1)的空间复杂度,所以严格意义上来讲解法1是不符合要求的,但是单从时间上来讲,出来的结果解法1更快。
为了符合空间复杂度的要求,这里采用了归并排序的思想,但是由于链表特殊的形式,不需要额外开辟数组空间储存已经merge完成的子列表,而只需储存已经排序好的子链表的头即可,这样就实现了要求的空间复杂度。
这边还利用到了双指针法的一个特性,**设置slow和fast指针,开始它们都指向表头,fast每次走两步,slow每次走一步,fast到链表尾部时,slow正好到中间,这样就将链表截为两段。**这个操作非常常见,在leetcode141和142中也有出现,可做对比

class Solution(object):
    def sortList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        def merge(head1,head2):
            if not head1:
                return head2
            if not head2:
                return head1
            dummy = ListNode(0)
            tmp = dummy
            while head1 and head2:
                if head1.val<head2.val:
                    tmp.next = head1
                    head1 = head1.next
                    tmp = tmp.next
                else:
                    tmp.next = head2
                    head2 = head2.next
                    tmp = tmp.next
            if not head1:
                tmp.next = head2
            if not head2:
                tmp.next = head1
            return dummy.next
        if not head or not head.next:
            return head
        slow = head;fast = head
        while fast.next and fast.next.next:
            slow = slow.next
            fast = fast.next.next
        lefthead = head
        righthead = slow.next
        slow.next = None
        lefthead = self.sortList(lefthead)
        righthead = self.sortList(righthead)
        head = merge(lefthead,righthead)
        return head

时间复杂度:O(Nlog(N))
空间复杂度:O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值