def merge(list1, list2):
results = []
while list1 and list2:
if list1[0] < list2[0]:
results.append(list1.pop(0))
else:
results.append(list2.pop(0))
results.extend(list1)
results.extend(list2)
return results
这是将2个已排序列表合并为1的标准算法。但是,如何将多个已排序列表合并为1?
l = [[8, 10, 12], [4, 5, 9], [2, 11]]
merge(l)
>>> [2, 4, 5, 8, 9, 10, 11, 12]
答案 0 :(得分:2)
您可以将自己的merge
与reduce
结合使用:
from functools import reduce
l = [[8, 10, 12], [4, 5, 9], [2, 11]]
merged = reduce(merge, l)
print(merged)
# [2, 4, 5, 8, 9, 10, 11, 12]
这是运行时间 O(kn)。您可以合并(唯一)对,直到剩下最后一个列表,这将使列表增加到 O(n log k)(因为要合并的列表数每次都会减少一半)。>
答案 1 :(得分:1)
您可以使用sorted()
对其进行排序:
from itertools import chain
l = [[8, 10, 12], [4, 5, 9], [2, 11]]
sorted(chain(*l))
给出结果:
[2, 4, 5, 8, 9, 10, 11, 12]
答案 2 :(得分:1)
您可以使用direct k-way merge和heap来实现queues:
import heapq
from collections import deque
def k_merge(*lists):
queues = [queue for queue in map(deque, lists)]
heap = []
for i, lst in enumerate(queues):
heap.append((lst.popleft(), i))
heapq.heapify(heap)
result = []
while heap:
value, index = heapq.heappop(heap)
result.append(value)
if queues[index]:
heapq.heappush(heap, (queues[index].popleft(), index))
return result
print(k_merge(*[[8, 10, 12], [4, 5, 9], [2, 11]]))
输出
[2, 4, 5, 8, 9, 10, 11, 12]
如果您有k
个列表和n
个元素,则此方法为O(nlogk)
答案 3 :(得分:0)
使用列表理解进行平整,然后进行排序
print(sorted([j for i in l for j in i]))
# [2, 4, 5, 8, 9, 10, 11, 12]
答案 4 :(得分:0)
from Queue import PriorityQueue
class Solution(object):
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
head = point = ListNode(0)
q = PriorityQueue()
for l in lists:
if l:
q.put((l.val, l))
while not q.empty():
val, node = q.get()
point.next = ListNode(val)
point = point.next
node = node.next
if node:
q.put((node.val, node))
return head.next
使用优先级队列可以优化比较过程
时间复杂度:O(n log(k)),其中k是链表的数量:
空间复杂度:
答案 5 :(得分:0)
一种简单有效的方法是heapq.merge:
>>> lists = [[8, 10, 12], [4, 5, 9], [2, 11]]
>>> list(heapq.merge(*lists))
[2, 4, 5, 8, 9, 10, 11, 12]
看一眼 CPython's implementation,它看起来类似于 direct k-way merge answer,所以我会猜测 heapq.merge
也是 O(n log(k))
,尽管docstring 不保证这一点。