合并排序数组算法

时间:2017-11-23 07:30:03

标签: python arrays algorithm sorting language-agnostic

我必须创建合并排序数组的算法。这是我做的:

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]

问题:

  1. 这是最好的方法吗?
  2. 算法复杂度kn^2?其中'k'是平均数组长度,n是数组的数量。
  3. 仅适用于kn大得多的情况吗?这样的kn在哪里有哪些快速解决方案成为更好的解决方案?

4 个答案:

答案 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}}不是太长,如果你想看看。