【问题标题】:Big O Notation of a certain algorithm?某种算法的大 O 表示法?
【发布时间】:2013-01-10 21:11:01
【问题描述】:

我有以下算法来确定两个数字 x 和 y 的最大公约数。我需要找到描述该算法的大符号并解释原因,但我不知道如何做到这一点。

有人可以看看我的代码并解释一下它是什么类型的大哦符号吗?

     public void question1(int x, int y){
            ArrayList divisorx = new ArrayList(); //the list of divisors of number x
            ArrayList divisory = new ArrayList();//divisors of number y
            ArrayList answerSet = new ArrayList();//the common divisors from both   
            //divisorx and divisory

            for(int i=1; i<=x; i++){//this loop finds the divisors of number x and 
                                    //adds them to divisorx
                    double remainder = x%i;
                    if(remainder==0){
                        //i is a divisor
                        divisorx.add(i);
                    }
            }
            for(int i2=1; i2<=y; i2++){//this loop finds the divisors of number y 
                                       //and adds them to divisory
                    double remainder2 = y%i2;
                    if(remainder2==0){
                        //i2 is a divisor
                        divisory.add(i2);
                    }
            }
      int xsize = divisorx.size();
      int ysize = divisory.size();

            for(int i=0; i<xsize; i++){//this massive loop compares each element of 
        //divisorx to those of divisory to find common divisors. It adds those common
        //divisors to the arraylist answerSet
               for(int j=0; j<ysize; j++){
                   if(divisorx.get(i)==divisory.get(j)){
                       //common divisor has been found
                       //add it to an answer array

                       answerSet.add(divisorx.get(i));

                   }
                }
            }
    Collections.sort(answerSet);//sorts the answerSet from smallest to greatest

    Object gcd = answerSet.get(answerSet.size()-1);//get the last element of the
                                                   //arraylist, which is the gcd       
    System.out.print("Your Answer: "+gcd);//print out the greatest common divisor
 }

【问题讨论】:

  • 看看循环和操作。例如。你sort 一个集合排序成本至少 O(n log n)
  • 一个起点是计算每行代码执行了多少次。很多行只执行一次,因此您主要需要密切注意循环。在这种特殊情况下,您的“计数”将根据 x 和 y。
  • 当你计算这样的东西时,重要的是查看每个数字的位数。根据幅度进行分析比较棘手。
  • 上述算法中有很多操作可以很容易的清理。例如,您可以执行 x->2,而不是从 1->x 开始。这将消除嵌套循环并用类似合并的小操作替换排序。即使您没有实现欧几里得方法,当前的代码似乎也是一种尽可能减慢直率方式的方法。

标签: java algorithm big-o


【解决方案1】:

前两个循环分别花费 O(X)O(Y)

N 的因数为 O(sqrt(N))(参见 cmets),因此 xsize 和 ysize 分别为 O(sqrt(X)) 和 O(sqrt(Y))。

因此,您的最后一个循环需要花费 O(sqrt(X).sqrt(Y))

answerSet 的大小为 O(min(sqrt(X),sqrt(Y))),因为它是 divisorxdivisory 的交集。

你对 answerSet 进行排序,即 O(min(sqrt(X),sqrt(Y)) log(min(sqrt(X),sqrt(Y)))

所有这些都是 O(X+Y),所以总复杂度是 O(X+Y)

【讨论】:

  • 你没有考虑到最后的排序。
  • 重新编辑,因为answerSet是O(N),排序是O(N log N),低于O(N²)
  • 再次编辑,对除数的数量有更严格的限制
  • N的除数不是sqrt(N)。取 2:它有 2 个除数(1 和 2)。
  • 大 O 表示法是关于渐近行为
【解决方案2】:

最大的复杂性是你拥有的两个嵌套的for循环Big Oorder,表示它是相对于输入大小的复杂度。在这里,您的输入大小是您在线性时间内找到的除数数(每个 1 个 for 循环),意思是 n + nO(n)。您示例中的排序通常具有n*log(n) 的平均复杂度。您的嵌套 for 循环是方形的,意思是 O(n^2)。您的订单就是O(n^2),因为这是计算中最大的复杂度。我们在多项式表达式中取最大次数,将所有复杂性相加,所以O(n^2 + n*log(n) + 2n) 这是二次多项式,因此 ~ O(n^2)

需要注意的是,顺序是空间和时间的复杂度较大。因此,如果内存使用复杂度大于计算复杂度,那么就会接管。

【讨论】:

  • 你也忘了answerSet上的排序
  • 当然是一般的nlog(n) 我加一下。
  • 感谢您的快速回复。但是,我认为因为 Big O 看到了最坏的情况,它会看到 Collections.sort() 的运行时间表示 O(nlog(n))。那么最终的答案真的不会是 O(nlog(n)) 吗?
  • @GeorgioMahugana O(n²) 项优于 O(n log n) 项。然而,随着更紧密的界限,这些术语最终都不会占主导地位(见我的回答)。另请注意,您可以将 Big O 表示法应用于除最坏情况之外的其他类型的复杂性分析,例如最佳情况复杂性。
【解决方案3】:

第一个循环正好完成X 次。
第二个循环 Y 次。
第三个循环肯定少于(X/2 + 1) * (Y/2 + 1) 次(因为一个数字N 最多可以有N/2 + 1 除数)。所以最坏的情况是O(XY/4) = O(XY)
列表answerSet 的大小相同,最多可以有XY/4 元素。 最后排序在O(nlogn)(根据javadoc)中完成,也就是说,在你的情况下,O(XYlog(XY))
所以最终的复杂度是O(X + Y + XY + XYlog(XY)) = O(XYlog(XY))
如果你想只用一个通用的N来表达复杂性,那么它就是O((N^2)logN),其中N = max(X, Y)

【讨论】:

  • 如果您在语义级别上查看第三个循环,您会发现您可以在answerSet 上获得更接近的 min(X,Y) 界限
  • @Khaur 是的,我看到并删除了我之前的评论。无论如何,根据您的说法,复杂性是O(X + Y + XY + NlogN)。你如何比较XYNlogN
猜你喜欢
  • 2014-03-23
  • 1970-01-01
  • 2013-11-25
  • 1970-01-01
  • 2014-07-09
  • 1970-01-01
  • 1970-01-01
  • 2017-09-28
  • 1970-01-01
相关资源
最近更新 更多