是否有一种算法方法可以在对数时间(O(logn))中找到未排序数组的最小值?或者只能在线性时间内使用?我不想平行。
由于
迈克尔
答案 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)
所以,如果你想做一些并行计算,你可能想尝试这种方法。