【问题标题】:Merging n/k sorted lists in nlog(n/k) - python在 nlog(n/k) 中合并 n/k 个排序列表 - python
【发布时间】:2018-05-16 19:39:37
【问题描述】:

我有 round(n/k) 个排序的子列表,这意味着每个子列表的长度是 k(以及一个长度小于 k 的单个列表)。我需要使用经典的 O(m+n) 合并函数将它们合并到单个 n 长度的排序列表中,因此需要 O(n*log(n/k))。

我有两个实现,一个带有递归(这似乎是正确的,但除非我改变递归深度,否则我不能这样做,而且我不明白为什么实际上,当输入列表的子列表不超过 10 个,每个子列表的长度为 k=3):

def merge_sorted_blocks(lst):
  i=0
  pairs_lst=[]
  n=len(lst)
  while i<n-1:
    pairs_lst.append(merge(lst[i],lst[i+1]))
    i+=2
  if n%2>0:
    pairs_lst.append(lst[n-1])
  if type(pairs_lst[0])!=list:
    return pairs_lst
  return merge_sorted_blocks(pairs_lst)

一个连续的输出列表和下一个子列表:

def merge_sorted_blocks(lst):
  pairs_lst=[]
  for i in lst:
    pairs_lst=merge(pairs_lst,i)
  return pairs_lst

但我不认为它具有所需的复杂性,更像是 O(n*(k+2k+...))=O(n^2))。 我发现这个线程表明它确实如此,但我不明白如何: https://math.stackexchange.com/questions/881599/on-log-k-for-merging-of-k-lists-with-total-of-n-elements

关于这些解决方案,我有什么遗漏吗?

【问题讨论】:

  • 请修正你的缩进。
  • 你读过堆数据结构吗? (这里是最小堆)

标签: python algorithm sorting time-complexity


【解决方案1】:

对于第二种算法,您的计算存在谬误。此外,您提到的线程与您的问题有所不同。

您有k 子列表,大小为n/k。由于merge函数对于两个大小为n1n2的集合的复杂度为O(n1 + n2),因此两个子列表第一次合并的计算复杂度为O(2 * n/k),当前子列表与第三个子列表的复杂度为O(3 * n/k)。因此,第二种算法的复杂度为O(2*(n/k) + 3*(n/k) + ... + k*(n/k)) = O(nk)

对于第一个实现,遗漏了一些细节。例如,如果只有一组(例如最后一步),则循环将失败。

另外,第一种算法的复杂度分析并不准确。如果要实现引用的算法,算法是O(n/k * log(k))

【讨论】:

  • 正如我提到的,每个子列表的大小是 k,并且所有子列表一起包含 n 个术语,这意味着有 n/k 个子列表
猜你喜欢
  • 1970-01-01
  • 2013-11-08
  • 2019-07-13
  • 1970-01-01
  • 2013-02-21
  • 2019-03-20
  • 2020-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多