【问题标题】:Time and space complexity of divide and conquer k-way-merge algorithm分治k-way-merge算法的时间和空间复杂度
【发布时间】:2018-08-24 08:41:45
【问题描述】:

假设 A 是一个由 k 个数组组成的数组。 每个内部数组都经过排序并包含 m 个元素。

鉴于此算法用于合并 A 中的 K 排序数组:

// A is array of sorted arrays  
K-arrays-merge(A)   
1.  if A.length == 1
2.      return first element of A
3.  half = length[A] / 2
4.  firstHalfArray = new array[half][m];
5.  secondHalfArray = new array[half][m];
6.  for (i = 0; i < half; i++)
7.      do firstHalfArray[i] = A[i];
8.  for (i = half; i < length[A]; i++)
9.      do secondHalfArray[i] = A[i];
10. secondHalfArray = Copy second half arrays from A
11. a = K-arrays-merge(firstHalfArray)
12. b = K-arrays-merge(secondHalfArray)
13. return merge(a,b) // This is a merge between two sorted arrays with time complexity of O(n)

为什么这个算法的时间复杂度是O(m*klogk)?

我的第一个想法是递归方法运行 logk 次,在每一轮中复制数组是 O(m * k) 并且合并排序是 O(m i log (m i)) 其中1 &lt;= i &lt;= logk

查看分治步骤时:

  1. 除法-计算中间点是O(1),复制数组是O(mk)
  2. 征服 - 2T(k/2) - 递归调用。
  3. 合并 - 合并排序复杂度为 O(m i log (m i)) 其中1 &lt;= i &lt;= logk

我不知道如何计算时间复杂度。这个算法的空间复杂度是多少?

【问题讨论】:

  • 问题标题是针对 k 路归并排序的,不是针对 k 路归并排序的。分而治之的方法意味着重复的 2 路(或小于 k 的某个数字)合并,直到产生单个合并运行,而不是进行单个 k 路合并。最大的空间需求发生在最终合并以产生单个排序运行时,看看你是否能弄清楚这方面的需求。

标签: arrays algorithm sorting divide-and-conquer


【解决方案1】:

如果我们假设n = mk,时间复杂度将是T(k) = 2T(k/2) + n + nn 用于数组复制,n 用于合并,2T(k/2) 用于递归调用。因此,算法的时间复杂度为O(nlog k) = O(mk log(k))

由于每次将数组的所有值都复制并存储在堆栈中,并且堆栈深度为O(log k),因此空间复杂度为O(n log k) = O(mk log k)

【讨论】:

  • 那么为了实现mk log k 的解决方案,必须使用最小堆吗?或者还有一种方法可以接近这个时间复杂度的解决方案?
  • 我犯了一个错误。数组都是排序的,所以最后一行的合并是 O(n)。这对答案有何影响?
  • 可以说 m= O(log k) 吗?如果是这样,为什么?如果不是,如何找到 O(mk log k) 的解?
  • @S.Peter 答案已更新。我对n/2 的计算有误。事实上,我们有 2T(k/2) 而不是 2T(n/2)
猜你喜欢
  • 2016-02-06
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
  • 2015-07-07
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
相关资源
最近更新 更多