合并k个有序链表

本文介绍三种解决LeetCode上K个排序链表合并问题的方法:暴力解法、优先队列优化和分治合并。详细分析了每种方法的时间和空间复杂度,提供了Python代码实现。

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

题目描述

leetcode链接:https://leetcode-cn.com/problems/merge-k-sorted-lists/

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例:

输入:
[
  1->4->5,
  1->3->4,
  2->6
]
输出: 1->1->2->3->4->4->5->6

分析

`N`:链表总结点数。
`K`:链表个数。

方法一:暴力解法,将所有链表的所有值存入数组中,快排排序,再将排序好的建立节点连接。
时间复杂度O(NlogN)
空间复杂度O(N)

方法二:优先队列优化,我们需要维护当前每个链表没有被合并的元素的最前面一个,K 个链表就最多有 K 个满足这样条件的元素,每次在这些元素里面选取 val 属性最小的元素合并到答案中。在选取最小元素的时候,我们可以用优先队列来优化这个过程。

时间复杂度:O(NlogK)
空间复杂度:O(K)

方法三:分治合并,

  • 将 K 个链表配对并将同一对中的链表合并;
  • 第一轮合并以后,K 个链表被合并成了 k 2 \frac{k}{2} 2k 个链表,平均长度为 2 n k \frac{2n}{k} k2n ,然后是 k 4 \frac{k}{4} 4k 个链表 k 8 \frac{k}{8} 8k 个链表等等;
  • 重复这一过程,直到我们得到了最终的有序链表。

在这里插入图片描述

代码

/*
方法一:暴力解法。
*/
# 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:
        nums = []
        for node in lists:
            while node:
                nums.append(node.val)
                node = node.next

        nums.sort()

        pre = ListNode(-1)

        node = pre 
        for i in nums:
            node.next = ListNode(i)
            node = node.next
            
        return pre.next
/*
方法二:优先队列
*/
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def mergeKLists(self, lists):
        import heapq

        heap, cur = [], [] #初始化优先队列,建立链表索引

        for index, node in enumerate(lists):
            if node:
                heapq.heappush(heap, (node.val, index))
            cur.append(node)

        pre = ListNode(-1)
        node = pre

        while heap:
            val, index = heapq.heappop(heap)
            node.next = ListNode(val)
            node = node.next

            cur[index] = cur[index].next
            if cur[index]:
                heapq.heappush(heap, (cur[index].val, index))

        return pre.next
/*
方法三:分治归并
*/
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def mergeKLists(self, lists):
        length = len(lists)
        if length==0:
            return None

        interval = 1
        while interval<length:
            for i in range(0, length-interval, interval*2):
                lists[i] = self.Merge(lists[i], lists[i+interval])
            interval *= 2

        return lists[0]

    def Merge(self, pHead1, pHead2):
        if not pHead1:
            return pHead2
        if not pHead2:
            return pHead1
        
        pMergeHead = None
        
        if pHead1.val < pHead2.val:
            pMergeHead = pHead1
            pMergeHead.next = self.Merge(pHead1.next, pHead2)
        else:
            pMergeHead = pHead2
            pMergeHead.next = self.Merge(pHead1, pHead2.next)
            
        return pMergeHead

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TransientYear

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值