我必须创建合并排序数组的算法。这是我做的:
import sys
lists = [[1,2,3],
[-100, 70],
[23, 50]]
pivot = [0] * len(lists) # [0, 0, 0]
finalSorted = []
for _ in range(sum(len(x) for x in lists)): # quantity of items in 2D array
smallest = sys.maxint
index_of_smallest = -1
for indx, list in enumerate(lists):
if pivot[indx] < len(list):
current = list[pivot[indx]]
if current <= smallest:
smallest = current
index_of_smallest = indx
finalSorted.append(smallest)
pivot[index_of_smallest] = pivot[index_of_smallest]+1
print(finalSorted) #[-100, 1, 2, 3, 23, 50, 70]
问题:
kn^2
?其中'k'是平均数组长度,n
是数组的数量。k
比n
大得多的情况吗?这样的k
和n
在哪里有哪些快速解决方案成为更好的解决方案? 答案 0 :(得分:1)
这是一个受欢迎的编程面试问题。我到目前为止看到的最优雅的解决方案如下:
from Queue import PriorityQueue
def mergeKLists(lists):
dummy = ListNode(None)
curr = dummy
q = PriorityQueue()
for node in lists:
if node: q.put((node.val,node))
while q.qsize()>0:
curr.next = q.get()[1]
curr=curr.next
if curr.next: q.put((curr.next.val, curr.next))
return dummy.next
全部归功于&gt; https://discuss.leetcode.com/topic/33609/10-line-python-solution-with-priority-queue
答案 1 :(得分:0)
这有点快 - 从我的实验中大约1.5倍:
from itertools import izip_longest
final = []
second = lambda x: x[1]
while any(lists):
idx, _ = min(enumerate(next(izip_longest(*lists, fillvalue=sys.maxint))), key=second)
final.append(lists[idx].pop(0))
编辑:我想如果你在理论意义上更多地考虑这个问题(即作为面试问题),这不是最好的答案 - 一个使用&amp;的好例子。滥用内置python函数:P
答案 2 :(得分:0)
关于leetcode的问题非常相似:https://leetcode.com/problems/merge-k-sorted-lists/description/ 合并k个排序列表和时间复杂度为O(Nlogk),其中N是k列表的总数。
算法的主要方法是构建一个大小为k的最小堆,并向其中添加元素。由于有关leetcode网站的详细解释,我建议您可以查看它。
答案 3 :(得分:0)
Python自己的标准库提供了一个基于堆的解决方案heapq.merge
,我假设它是O(kn log n)。我怀疑你能比O(kn log n)做得更好。
heapq.merge
的{{3}}不是太长,如果你想看看。