字节、快手、阿里面试真题---分治算法 | 优先级队列:力扣23. 合并K个排序链表

1、题目描述:

在这里插入图片描述

2、题解:

方法1:分治算法:

链表两两合并

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        #分治
        if not lists:return
        n = len(lists)
        return self.merge(lists,0,n-1)
    def merge(self,lists,left,right):
        if left == right:
            return lists[left]
        mid = left + (right - left) // 2
        l1 = self.merge(lists,left,mid)
        l2 = self.merge(lists,mid+1,right)
        return self.mergeTwoLists(l1,l2)
    def mergeTwoLists(self,l1,l2):
        if not l1:return l2
        if not l2:return l1
        if l1.val < l2.val:
            l1.next = self.mergeTwoLists(l1.next,l2)
            return l1
        else:
            l2.next = self.mergeTwoLists(l1,l2.next)
            return l2

方法2:优先级队列

思路:设置一个哑结点,
初始化head数组:先把各个链表的头结点放在head数组中,
然后循环处理优先队列的第一个元素,直到Head为空,
返回哑结点的下一个结点

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        # 优先级队列
        import heapq
        head = []  # 存储优先级队列的元素,初始时有K个元素,分别都是链表数组中的各个链表的头结点
        res = ListNode(0)  # 哑结点
        p = res
        for i in range(len(lists)):  # 初始化head
            if lists[i]:
                heapq.heappush(head, (lists[i].val, i))
                lists[i] = lists[i].next
        while head:
            val, idx = heapq.heappop(head)
            p.next = ListNode(val)
            p = p.next
            if lists[idx]:
                heapq.heappush(head, (lists[idx].val, idx))
                lists[idx] = lists[idx].next
        return res.next

方法3:朴素法
最后稍微提一下,朴素(暴力)解法,也就是我们一开始能想到的。可以写个循环,让链表数组的链表进行两两链表合并(也就是利用两两链表的合并函数)

3、复杂度分析:

方法1:
时间复杂度:O(kn x logk),k组链表,n为k组链表的最大长度
空间复杂度:O(logk)
方法2:
时间复杂度:O(kn×logk),考虑优先队列中的元素不超过 k 个,那么插入和删除的时间代价为 O(logk),这里最多有 kn 个点,对于每个点都被插入删除各一次,故总的时间代价即渐进时间复杂度为 O(kn×logk)。
空间复杂度:O(k)这里用了优先队列,优先队列中的元素不超过 k 个,故渐进空间复杂度为 O(k)。
方法3:
时间复杂度:O(k^2*n)
空间复杂度:O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值