代码之家  ›  专栏  ›  技术社区  ›  RudziankoÅ­

合并排序数组算法

  •  1
  • RudziankoÅ­  · 技术社区  · 7 年前

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

    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. Is算法复杂性 kn^2 ? 其中“k”是平均数组长度,并且 n 是数组的数量。
    3. 它只适用于以下情况吗 k 比现在大得多 n ? 这样做的意义何在 k n 这里有哪些快速排序成为更好的解决方案?
    4 回复  |  直到 7 年前
        1
  •  1
  •   user1767754    7 年前

    这是一个流行的节目采访问题。到目前为止,我看到的最优雅的解决方案是:

    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
    

    https://discuss.leetcode.com/topic/33609/10-line-python-solution-with-priority-queue

        2
  •  0
  •   C. Feenstra    7 年前

    这要快一些——大约是我实验的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))
    

    编辑:我想如果你更多地从理论的角度思考这个问题(例如,作为一个面试问题),这不是最好的答案——这是一个使用&但是滥用内置python函数:P

        3
  •  0
  •   程名锐    7 年前

    关于leetcode有一个非常类似的问题: https://leetcode.com/problems/merge-k-sorted-lists/description/ 它合并k个排序列表,时间复杂度为O(Nlogk),其中N是k个列表的总数。

    该算法的主要方法是构建一个大小为k的最小堆,并向其中添加元素。因为leetcode网站上有详细的解释,我建议你可以看看。

        4
  •  0
  •   Paul Panzer    7 年前

    Python自己的标准库提供了基于堆的解决方案 heapq.merge 我假设它是O(kn log n)。我怀疑你能做得比O(kn log n)更好。

    source 属于 heapq。合并 不是太长,如果你想看看的话。