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)