Java 另一个时间复杂性问题

Java 另一个时间复杂性问题,java,math,time,complexity-theory,Java,Math,Time,Complexity Theory,我已经解决了这些问题,所以我不是在寻找一个直截了当的答案。我正在寻找有关我是否正确操作的指导,如果没有,可能需要一些关于我不正确原因的解释。:) 所以我有两个问题。我已经在为什么我得到我的答案中评论了我的逻辑。如果有人能确认我做的正确吗 public static Integer findTripleB(int[] anArray) { //Method Variable: n if (anArray.length <= 2) { return false

我已经解决了这些问题,所以我不是在寻找一个直截了当的答案。我正在寻找有关我是否正确操作的指导,如果没有,可能需要一些关于我不正确原因的解释。:)

所以我有两个问题。我已经在为什么我得到我的答案中评论了我的逻辑。如果有人能确认我做的正确吗

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)
public静态整数findTripleB(int[]anArray){
//方法变量:n
if(anArray.length=0&&anArray[j]>元素){//TC log(n)
anArray[j+1]=anArray[j];//TC 1
j--;///tc1
}
anArray[j+1]=元素;//TC 1
}//总TC:(2n+2)(1+1+log(n)(2))=(2n+2)(2+2log(n))=4n+(2log(n))(2n)+4+4log(n)
//检查数组是否包含三个连续的
//相同值的元素
对于(inti=0;i
为了获得最佳的时间复杂度,我得到了O(1),因为如果数组>=长度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
布尔findTripleA(int[]anArray){//方法变量:n
如果(anArray.length=3){
返回true;
}//TC 1
}//总TC:(2n+2)(1+2n+2+1)=(2n+2)(2n+4)=4n2+12n+8
返回false//TC 1
}//总时间复杂度:4n2+12n+9
对于最佳情况,与第一个问题O(1)相同。对于最坏的情况,O(n^2)


这些是否正确?如果不正确,原因为何?再说一遍,我不是在寻找答案。我在寻找指导,因为我的教授似乎不想帮忙,而班上的其他人也一样困惑。

一般来说,试图超越数量级是没有意义的。如果有一个N平方项,你可以称它为O(N**2),保持不变。如果你想更准确,我建议在上面运行一个分析器。。。需要注意的是,热点优化、JIT不确定性和GC时间共同导致在Java中很难精确测量性能。

对于第一个示例,这里有几点:

算法的复杂性分析不是关于算法的单一情况(例如数组大小为2),而是关于算法在任意大小输入的最佳/最差/平均情况下所需的时间(任何给定大小的数组)。从技术上讲,当n(输入的大小)趋于无穷大时,您可以对行为进行分析。因此,循环前的if语句不会影响算法的渐近最佳情况性能

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

然而,还不完全清楚内部while循环还要多长时间 如果我们的数组大小是原来的两倍,则需要。毕竟,它不会消失 通过整个阵列。事实上,平均而言,它只会通过 如图所示,大约一半的阵列,有时更少, 在排序的早期,有时更多,在排序的后期,但是 平均每个阵列都有一个。即使这样,它通常也不会一直走下去 降到索引0。它将平均扫描大约一半的区域 在找到正确的点之前已排序的集。因此,合理的做法是 估计内部while循环必须遍历数组的¼ 每次通过外部for循环。排序集必须是 搜索平均为数组大小的一半,并且平均必须 在找到正确的位置之前,先搜索已排序集的一半

但是,即使只是阵列的¼,如果 阵列大小加倍——1000的¼为250,2000的¼为500,是1000的两倍 很因此,当数组大小加倍时,内部while循环将 平均两倍的时间,而且必须执行两倍的次数 由外部为循环。因此,插入排序需要4倍的时间来完成 当数组大小加倍时运行。它的运行时间与n^2成正比, 我们说它是O(n^2)

最好的情况是,你也错了。即使它“刚刚返回”,您仍然要经历与数组中元素数量成比例(实际上,相等)的大量比较(即使它只有2个元素)。因此,最好的情况是O(n)比较,因为您必须检查每个元素是否处于正确的位置,但是O(1)交换(如果它已经按正确的顺序排序,并且没有任何地方可以交换)

此外,在代码中,在同一方法的一个位置返回布尔值,在另外两个位置返回整数。这没有道理


希望这一切都清楚了。

如果返回,为什么返回下面的代码会执行?我记得,如果一个方法返回某些东西,它下面的代码就不会执行。您只需要运行第一个if()。因为算法的复杂性分析不是关于一个问题的单个实例,而是当n->无穷大时,算法渐进地需要多长时间。也就是说,对于一般的一类问题,或者在本例中,对于任意大小的数组,这是有意义的。我只是不习惯看过去的回报,我想。所以对于第一种情况,它是最佳情况O(n)和最坏情况O(n^2)…对于第二种情况,它也是最佳情况O(n)和最坏情况O(n^2),因为我有一个嵌套的for循环而不是插入排序?不。第二个循环是O(n^2)的最佳情况,因为你在外循环和完全在内循环中遍历数组。这种嵌套循环往往会导致