另一个时间复杂问题

时间:2014-01-31 20:13:06

标签: java math time complexity-theory

我已经完成了这些问题,所以我不是在寻找一个直截了当的答案。我正在寻找关于我是否正确执行此操作的指导,如果没有,可能会解释为什么我不正确。 :)

所以我有这两个问题。我已经评论了我为什么得到答案的逻辑。如果有人可以请证实我这样做是正确的吗?

public static Integer findTripleB(int[] anArray) {
//Method Variable: n
       if (anArray.length <= 2) {
          return false;
       }                //Time Complexity: 1
       // use insertion sort to sort anArray
       for (int i = 1; i < anArray.length; i++) {//TC 1+(n+1)+n
          // insert anArray[i]
          int j = i-1; //TC 1
          int element=anArray[i]; //TC 1
          while (j >= 0 && anArray[j] > element) {//TC log(n)
             anArray[j+1] = anArray[j]; //TC 1
             j--; //TC 1
          }
          anArray[j+1] = element; //TC 1
       } //Total TC: (2n+2)(1+1+log(n)(2)) = (2n+2)(2+2log(n)) = 4n+(2log(n))(2n)+4+4log(n)
       // check whether anArray contains three consecutive 
       // elements of the same value
       for (int i = 0; i < anArray.length-2; i++) {//TC 1+n-1+n
          if (anArray[i] == anArray[i+2]) {//TC 1
             return new Integer(anArray[i]);//TC 1
          }
       }//Total TC: (2n)(2) = 4n
       return null;//TC 1
        }   //TOTAL TIME COMPLEXITY: 5+8n+4nlog(n)+4log(n)

为了获得最佳的时间复杂度,我得到了O(1),因为如果数组是&gt; =长度2,它将返回。在最坏的情况下,我想出了O(n * log(n))。

还有一个更简单的问题,

boolean findTripleA(int[] anArray) { //Method Variable: n
   if (anArray.length <= 2) {
      return false;//TC 1
   }//TC 1
   for (int i=0; i < anArray.length; i++) {//TC 1+n+1+n
      // check if anArray[i] occurs at least three times 
      // by counting how often it occurs in anArray
      int count = 0;//TC 1
      for (int j = 0; j < anArray.length; j++) {//TC 1+n+1+n
         if (anArray[i] == anArray[j]) {
            count++;
         }//TC 1
      }//Total TC: 2n+2
      if (count >= 3) {
         return true;
      }//TC 1
   }//Total TC: (2n+2)(1+2n+2+1) = (2n+2)(2n+4) = 4n2+12n+8
   return false;//TC 1
}//TOTAL TIME COMPLEXITY: 4n2+12n+9

最好的情况,与第一个问题相同,O(1)。对于最坏的情况,O(n ^ 2)。

这些是否正确,如果没有,为什么不呢?再一次,我不是在寻找答案。我正在寻找指导,因为我的教授似乎并不想提供帮助,而其他同学也同样困惑。

2 个答案:

答案 0 :(得分:2)

第一个例子的几点:

算法的复杂性分析不是关于算法的单个案例(例如,数组大小为2),而是关于算法将在多长时间内采用的最佳/任意大小输入的最差/平均情况(所以任何给定大小的数组)。从技术上讲,您进行分析,查看行为,因为n(输入的大小)趋于无穷大。因此,循环之前的if语句不会影响算法的渐近最佳情况

插入排序的最坏情况是O(n ^ 2 )。如果输入数组已经排序但顺序相反,则可以获得此类时间。所以你对第一种情况的结论是错误的。因此,我不必写出为什么会出现这种情况的冗长描述,这里解释为什么它来自here的O(n ^ 2):

  

然而,内部while循环多长时间并不完全清楚   如果我们有两倍的数组大小将采取。毕竟,它不会去   通过整个阵列。事实上,平均而言,它只能通过   大约一半的数组,如我们的图表所示,有时更少,   在排序的早期,有时更多,在后面的那种,但是一半   数组平均。即便如此,它通常不会一路走下去   它将平均再次扫描约一半   在找到正确的位置之前排序的集合。所以,这是合理的   估计内部循环必须遍历数组的1/4   每次通过外部for循环。必须排序的集合   搜索平均值是阵列大小的一半,平均而言必须是   在找到正确的位置之前,搜索已排序的一半。

     

但是,即使它只是阵列的1/4,如果它仍然会翻倍   数组大小加倍 - 1000的1/4是250,2000的1/4是500,两倍   许多。因此,当数组大小加倍时,内部while循环占用   平均两倍,并且必须执行两次   通过外部for循环。因此插入排序需要4倍的时间   当数组大小加倍时运行。它的运行时间与n ^ 2成正比,   我们说它是O(n ^ 2)。

对于最好的情况,你也错了。即使它“只是返回”,你仍然会经历与数组中元素数量成比例(实际上,相等)的多个比较(即使它只是2个元素)。所以最好的情况是O(n)比较,因为你必须检查每个元素是否在正确的位置,但O(1)交换(以防万一)它已经按正确的顺序排序,没有任何东西可以在任何地方交换。)

此外,在您的代码中,您将在一个位置返回一个布尔值,并在同一方法的另外两个位置返回Integers。这没有意义。

希望这一切都很清楚。

答案 1 :(得分:0)

一般来说,试图超出数量级是没有意义的。如果有一个N平方项,你可以称之为O(N ** 2)并保留它。如果你想要更准确,我建议在其上运行一个分析器......需要注意的是,热点优化和JIT不确定性以及GC时间都会合谋在Java中对性能进行精细测量。