当前位置: 首页 > 知识库问答 >
问题:

计算大O复杂度

山森
2023-03-14

在最近的一次测试中,我们得到了一个函数来计算未排序的ArrayList中出现了多少个double(不是原语double,而是一个项目出现了两次)。

我正确地确定了Big O复杂度为O(N^2),但由于我错误地确定了全部复杂度,因此只获得了部分学分。函数如下:

public static <T> int countDoubles(ArrayList<T> list, int index, Comparator<? super T> cmp) {
    if (index >= list.size())
        return 0;
    int count = 0;
    for (int i = index + 1; i < list.size(); i++) {
        if (cmp.compare(list.get(index), list.get(i)) == 0)
            count++;
    }
    return count + countDoubles(list, index + 1, cmp);
}

在他刚刚发布的考试解决方案中,他给出了这样的解释:

输入集合中有N个项,该方法通过一个缩减步骤反复调用自己,该步骤生成一个新索引N次,直到达到基本情况(集合结束)。对于每个递归帧,都有一个For循环,该循环在每个帧中重复处理集合中少一个元素,直到它到达集合的末尾。因此,有N个递归调用,第一个调用有N-1个步骤,第二个调用有N-2个步骤,第三个调用有N-3个步骤,依此类推,直到到达数组末尾。此行为在上界复杂性方面具有二次增长,因为它将呈现以下表达式:

T(N)=(N-1)(N-2)(N-3)。。。1=N(N-1)/2=((N^2)/2)-(N/2)=O(N^2)

为了正确理解这一点,我尝试绘制一个大小为10的简单数组,每次将其检查的大小减少一个。

[] [] [] [] [] [] [] [] [] []
   [] [] [] [] [] [] [] [] []
      [] [] [] [] [] [] [] []
         [] [] [] [] [] [] []
            [] [] [] [] [] []
               [] [] [] [] []
                  [] [] [] []
                     [] [] []
                        [] []
                           []

计算递归级别的意义在于N。计算每个元素得出9 8…=45考虑到100(N级递归*N个元素)是100,我不明白N/2从何而来,更不用说((N^2)/2)-(N/2)。

任何解释都是非常感谢的,因为我一直在寻找过去的一个月,似乎不能完全理解我错过了什么。非常感谢。

共有1个答案

姬奇思
2023-03-14

1M的整数之和是((M 1)*M)/2。这只是一个数学事实(通常通过归纳法证明)。如果您不相信,请尝试一些示例。

算法的第一次传递执行N-1比较,每一级递归执行一次比较,直到最后一级递归执行1比较。因此,比较的总数(对于所有递归级别)是从1到N-1的整数之和。用公式中的N-1代替M,得出的比较总数为N*(N-1))/2。

从那以后就只是代数了

(N * (N-1)) / 2 = (N * N - N) / 2 = ((N^2) / 2) - (N / 2)

这样分解的原因是因为big-O只关心指数最大的N。当然,big-O也不关心常量。所以你扔掉了(N/2),忽略了/2,答案是O(N^2),这是最大的crck o'...

嗯,别介意我对这件事的看法,事情就是这样。

 类似资料:
  • 我遇到了一个问题,需要计算非常大的阶乘的值。我用两种不同的方法在C中解决了这个问题,但只想知道我的复杂性分析是否准确。 在任何一种方法中,我都将非常大的数字表示为向量,其中表示最低有效数字,最后一个索引处的值表示最高有效数字。版本1的代码可以在这个要点中找到。 给定上面的代码,似乎是其中是给定的整数,是向量表示的数字。我的逻辑是,我们将执行一些与结果数字的长度成比例的步骤,以便生成一个表示的向量。

  • 给定一个整数数组arr,计算元素x,使得x 1也在arr中。如果arr中有重复项,请分别计数。 示例1:输入:arr=[1,2,3]输出:2说明:1和2被计数,因为2和3在arr中。 示例2:输入:arr=[1,1,2]输出:2解释:1计数两次,原因2在arr中。 示例3:输入:arr=[1,1,3,3,5,5,7,7]输出:0说明:没有计算数字,因为arr中没有2、4、6或8。 示例4:输入:a

  • 我正在学习算法和数据结构课程。 今天,我的教授说下面算法的复杂度是2n。 我一直等到课程结束,走近他,告诉他我真的相信这是一个O(n)算法,我做了计算来证明它,并想给他们看,但他继续说它不是,没有给我任何令人信服的解释。 该算法是递归的,具有以下复杂性: 我计算它是一个,这样: 让我们展开 当T中的项为1时,我们停止,即: n/(2i)=1== 替换后,我们获得 由于该算法是从关于合并排序的课程中

  • 在研究算法和数据结构时,我手动评估脚本的BigO复杂性。有没有一种方法,比如说任何Python IDE或包中的一个按钮,可以计算任何给定函数或程序的BigO? 更新: 假设我有 为什么我不能编写一个分析器,它会告诉我可以,你可以通过索引及其O(1)访问数组(列表),或者 好的,您进行了完全扫描,因此复杂性为O(n) 等等

  • 给定已排序的两个单链表,合并这些列表。 示例: list1: 1 2 3 5 7 list2: 0 4 6 7 10 --- 尽管这个解决方案非常简单,并且有几个不同的问题实现,不管是否使用递归(如下所示http://www.geeksforgeeks.org/merge-two-sorted-linked-lists/见方法3), 我想知道这个实现有多复杂: 如果其中一个列表是空的,只需返回另一

  • 我知道,对于迭代,递增。