使用并发在旋转的排序数组中查找最小值

时间:2018-10-27 11:33:02

标签: arrays algorithm performance time-complexity

这是面试问题。
在第一部分中,我被要求在旋转的排序数组中查找最小值(例如,将排序数组[1,2,3,4]旋转为[3,4,1,2])。 可以找到用于执行此操作的算法here

然后我被要求通过使用并行计算来改进算法。那是我的建议:

  1. 假设我们可以并行运行k个线程,请将数组划分为k个相等大小的子数组(也许最后一部分除外)。
  2. 在k个子数组中的每个数组上执行上述算法。
  3. 从k个算法运行中返回最小值。

面试官说算法的运行时间不够好。您知道更好的解决方案吗?

1 个答案:

答案 0 :(得分:-1)

让我们假设您有 n + 1 个硬件线程。您可以让 n 个线程处理该数组,每个线程“负责” 1个条目并在O(1)时间内完成,其余线程等待结果。为了提高效率,应该事先启动线程并使用索引变量( i )进行初始化,否则初始化本身将为O(n)时间。每个线程中的进程可能是:

if arr[i] > arr[(i + 1) mod n]
  SharedMemResult = arr[(i + 1) mod n]

这显然是O(1)时间,并且所有“主”线程必须做的工作都读SharedMemResult,直到它改变为止(当然,这需要初始化为某个极限值,并且应该设置内存屏障用来防止重新排序...)。

使用相同的概念,我们可以利用 m 个线程,其中每个线程在(n * i / m)->(n *(i + 1)/ m-1 )在O(log(n / m))的时间内进行验证,然后将其验证为真实的最小值(仅与范围中第一项相关的是最小值,但对于大多数范围来说都是这种情况)。

结果是一种可以解决O(log(n / m))时间问题的算法。