我正在学习算法和数据结构课程。
今天,我的教授说下面算法的复杂度是2n。
我一直等到课程结束,走近他,告诉他我真的相信这是一个O(n)算法,我做了计算来证明它,并想给他们看,但他继续说它不是,没有给我任何令人信服的解释。
该算法是递归的,具有以下复杂性:
{ 1 if n=1
T(n) = {
{ 2T(n/2) otherwise
我计算它是一个O(n)
,这样:
让我们展开T(n)
T(n) = 2 [2 * T(n/(2^2))]
= 2^2 * T(n/(2^2))
= 2^2 * [2 * T(n/(2^3))]
= 2^3 * T(n/(2^3))
= ...
= 2^i * T(n/(2^i)).
当T中的项为1时,我们停止,即:
n/(2i)=1==
替换后,我们获得
T(n) = 2^log n * T(1)
= n * 1
= O(n).
由于该算法是从关于合并排序的课程中跳出来的,所以我注意到了如何进行合并排序,这是出了名的O(n log n)
我的问题是:
是的,这也是一个通风口。
很明显,满足递归关系的函数是O(n),这是正确的。这是显而易见的,因为它说,一个给定问题的复杂性是一个大小为一半的问题的两倍。你不可能得到比这更多的线性。例如,使用线性搜索搜索包含1000个元素的列表的复杂性是搜索包含500个元素的列表的复杂性的两倍。
如果您的教授也是正确的,那么您可能对满足该递归的复杂性不正确。或者,有时对如何测量输入大小存在一些混淆。例如,整数n
在指定它所需的位数上是指数的。例如——整数n
的蛮力试除法是O(sqrt(n))
,这比O(n)
好得多。这与蛮力分解对于例如破解RSA基本上毫无价值的事实并不矛盾的原因是,对于256位密钥,相关的n
大约是2^256
。
计算给定关系的时间复杂度是正确的。如果我们测量的输入大小是n(我们应该这样做),那么你的教授声称时间复杂度是2 n是错误的。
你可能应该和他讨论一下,消除你可能存在的误解。
证明-1
这个递归属于主定理的情况-3,具有
因此Logba=1,大于-∞. 因此,运行时间为Θ(n1)=Θ(n)。
证明-2
直观地说,您正在将大小为n的问题分解为大小为n/2的两个问题,并且将两个子问题的结果合并的成本为0(即,在循环中没有常数分量)。
因此,在最底层,您有n个成本为1的问题,导致n*O(1)的运行时间等于O(n)。
编辑:为了完成此答案,我还将为您提出的特定问题添加答案。
我的论证有谬误吗?
不,这是正确的。
最后一种情况不是违反直觉吗?
这绝对是违反直觉的。参见上面的证明-2。
在最近的一次测试中,我们得到了一个函数来计算未排序的ArrayList中出现了多少个double(不是原语double,而是一个项目出现了两次)。 我正确地确定了Big O复杂度为O(N^2),但由于我错误地确定了全部复杂度,因此只获得了部分学分。函数如下: 在他刚刚发布的考试解决方案中,他给出了这样的解释: 输入集合中有N个项,该方法通过一个缩减步骤反复调用自己,该步骤生成一个新索引N次,直到达
Leetcode问题https://leetcode.com/problems/count-binary-substrings/ 该解决方案有效,但我很难提出递归解决方案的时间复杂度。 每当循环遇到s.charAt(i)!=s.charAt(i 1)时,它都会进行递归调用以展开,直到达到基本大小写或其他部分。 因为我遍历整个字符串,所以for循环是O(n)。但是如何确定将进行的递归调用的数量,因为
我有一个使用递归打印斐波那契级数的程序。有更好的方法,但我被要求使用递归,所以我不得不这样做。 这是程序: 我知道这对于斐波那契级数来说真的是一种糟糕的方法,从上面可以清楚地看出,当项超过35时,程序需要很多时间才能完成。 我看了这个答案,不明白他们是怎么解决的,但看起来 fibo(int n)的时间复杂度为O(2^n) 我可能完全错了,但我只想: 这个完整程序的时间复杂度是多少,简要解释一下您是
我有一个算法可以检查是否可以解决游戏行。游戏行是一个正整数数组,其中最后一个元素为 0。游戏标记从索引 0 开始,沿着数组移动它所在的整数指示的步数。 例如,[1,1,0]返回true,而[1,2,0]返回false。标记也可以向左或向右移动以解决游戏。也就是说,[3,3,2,2,0]是可解的。 我尝试了一些游戏行示例,并计算了最坏情况下的时间复杂度: 其他情况下给我的数字,我找不到与输入大小的关
我想确定两个函数的复杂性。 第一个我只需要知道我的解决方案是否正确,第二个是因为我正在努力寻找解决方案的两个递归调用,如果可能的话,最好进行工作,这样我就可以了解它是如何完成的。 第一: 尝试的解决方案: 第二: 任何帮助将不胜感激。 当做