以对数时间查找未排序数组中的最小值

时间:2011-03-24 15:24:11

标签: arrays complexity-theory big-o minimum

是否有一种算法方法可以在对数时间(O(logn))中找到未排序数组的最小值?或者只能在线性时间内使用?我不想平行。

由于

迈克尔

6 个答案:

答案 0 :(得分:12)

如果列表未排序,则搜索必须至少是线性的。您必须至少查看一次每个项目,因为您未查看的任何内容可能小于您已经看过的内容。

答案 1 :(得分:2)

它可能不是线性时间,因为在lg n 步骤中,您只能检查lg n 元素,并且由于它们未排序,因此值不包含任何信息数组中的其他值。

答案 2 :(得分:2)

一般而言,并行无济于事。如果您有比 n 更多的处理器,并且您没有计算加载数据所需的时间,即O( n ,然后是的,你可以在对数时间内完成。但是假设你有每个处理器10个数字。这需要一定的时间。现在为每个处理器制作20个数字。每个处理器需要两倍的时间来处理其数字,然后才能并行比较彼此的结果。 O( n )+ O(log n )= O( n )。

答案 3 :(得分:0)

你的意思是最小值?

这是线性的 - 你遍历你的数组,保存最不为人知的元素的位置(或值本身),并将每个元素与之比较。相反,元素是否更低。最后,您拥有最小元素的位置(或值)。

我在C ++ 0x中做了一个简短的例子:

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
   std::vector<int> array({5, 3, 2, 7, 5, 1, 9});

   int min = array[0];

   std::for_each(array.cbegin(), array.cend(), [&min] (const int cur) {
      min = std::min(cur, min);
   });

   std::cout << min;
}

您可以在Ideone

执行此操作

答案 4 :(得分:0)

线性不是,但如果使用某种修改的快速排序,它可能比小于10个元素的线性更快。我怀疑你在寻找阵列中不到10个项目:)

实现它的另一种方法是进入SSE指令的世界。

一个可以提供帮助的OPCODE是CMPLEPS,它可以同时并行比较4个标量。

如果您不愿意在并行代码中执行此操作,但我非常怀疑您是否愿意使用SSE汇编指令。

答案 5 :(得分:0)

你也可以对此进行分而治之的递归算法,代码:

private static Integer array[];

private static Integer findMinimum(int startIndex, int endIndex){

   //base case
   if(startIndex + 1 == endIndex || startIndex == endIndex){
     return array[startIndex] < array[endIndex] ? array[startIndex] : array[endIndex];
   }

   //recursive case
   int a = findMinimum(startIndex, (startIndex + endIndex) / 2 );   
   int b = findMinimum( (startIndex + endIndex) / 2 + 1, endIndex); 

   return Math.min(a, b);
}

此算法的运行时间为: O(n)

但是,如果您有N个处理器(我知道这不是一个“有效”的真实世界场景,这仅适用于理论讨论)。您可以进行并行计算,并且运行时间为: O(log n)

所以,如果你想做一些并行计算,你可能想尝试这种方法。