【问题标题】:Finding the minimum in an unsorted array in logarithmic time在对数时间内找到未排序数组中的最小值
【发布时间】:2011-07-22 05:55:34
【问题描述】:

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

谢谢

迈克尔

【问题讨论】:

    标签: arrays complexity-theory big-o minimum


    【解决方案1】:

    这不可能是线性时间,因为在 lg n 步骤中您只能检查 lg n 元素,并且因为它们是未排序的,所以这些值不包含关于数组中的其他值。

    【讨论】:

    • 但是在线性时间内可能的!
    • Lg n 是线性时间。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      你的意思是最小值?

      这是线性的——你遍历你的数组,保存最不为人知的元素的位置(或值本身),然后将每个元素与之进行比较。是不是元素较低保存它。最后你有最小元素的位置(或值)。

      我在 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】:

        线性不是,但是如果使用某种修改过的快速排序,它可以比线性快于少于 10 个元素。我怀疑你正在寻找少于 10 个数组中的项目 :)

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

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

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

        【讨论】:

          【解决方案5】:

          一般来说并行并没有帮助。如果您的处理器多于 n,并且 您不计算加载数据所需的时间,即 O(n) ,那么是的,您可以在对数时间内完成。但是假设每个处理器有 10 个数字。这需要一定的时间。现在让每个处理器有 20 个数字。在并行比较彼此的结果之前,每个处理器将花费两倍的时间来处理其数字。 O(n) + O(log n) = O(n)。

          【讨论】:

            【解决方案6】:

            你也可以有一个分而治之的递归算法,代码:

            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)

            因此,如果您想做一些并行计算,您可能想尝试这种方法。

            【讨论】:

              猜你喜欢
              • 2012-01-12
              • 2021-12-16
              • 2019-09-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-03-31
              • 1970-01-01
              • 2020-01-22
              相关资源
              最近更新 更多