这个算法的时间复杂度是多少
Posted
技术标签:
【中文标题】这个算法的时间复杂度是多少【英文标题】:What will be the time complexity of this algorithm 【发布时间】:2020-08-03 09:53:18 【问题描述】:我对竞争性编程和大 O 表示法非常陌生。
public void function(int n)
for(int i = n; i > 0; i/=3)
for(int j = 0; j < i; j++)
System.out.println("Hello");
这是算法。 据我所知时间复杂度。它定义了运行时间如何受到输入数量的影响。
所以如果我们举个例子 如果'n'是10。 外循环运行 log n 次,内循环运行 'i' 次。
内部循环相对于 'i' 而不是 'n' 运行。 所以我对如何计算时间复杂度有点困惑。 我认为是 O(log n)。如果我错了,请纠正我。
是 O(log n) 还是 O (n log n) 或 (n^2)。 这个你能帮我吗。 谢谢。
【问题讨论】:
代码中似乎有错误。变量 i 初始化为 0,0 乘以 3 仍为 0。它陷入了无限循环 【参考方案1】:我会尽量用最简单的术语来解释
外部循环将简单地以 3 次为底运行 log(n)。
因为,i 每次都减少 3 倍。完成的总功等于:
n + n/3 + n/9 + n/27 + .... n/(3^log(n))
因为,n/3 + ... + n/(3^log(n)) 将永远小于 n
例如让 n = 100 那么,100 + 100/3 + 100/9 + 100/27 + ... = 100 + (33.3 + 11.11 + 3.7 + ...)
我们可以清楚地看到括号中的项总是小于100
整个解决方案的总时间复杂度为 O(n)。
【讨论】:
。在你回答的后半部分,我相信你正在描述内部循环所做的工作。我正确吗? 是的,n个工作在内循环的第一次迭代中完成,n/3在内循环的第二次迭代中完成,依此类推... 其实内循环的总迭代次数好像是~n*k/(k-1)(其中k是对数的底),即n*3/2在这种情况下。 一些数学事实:1 + 1/3 + 1/9 + ... = 3/2
是的,我们可以使用 GP sum 公式得到这个结果。【参考方案2】:
实际上它永远不会终止,因为i=0
和更新是i *= 3
所以i
将保持0
所以我们可以说O(+oo)
假设你的意思是for(int i =1...
,那么它的O(n)
:
O(log_3 n)
因为我们一直乘以 3
内部循环将执行O(log_3 n)
次,迭代计数为(1 + 3 + 9 + 27 + ... + 3^log_3(n))
,这显然是一个几何级数,求解得到大约3^log_3(n))
,根据日志规则得到n
,所以这个循环需要O(n)
对于所有迭代,总复杂度为O(n)
【讨论】:
抱歉代码有一点小错误,请查看更新版本@Photon【参考方案3】:为您的代码:
for(int i = n; i > 0; i/=3)
for(int j = 0; j < i; j++)
System.out.println("Hello");
内循环变量 j 取决于外循环变量 i,因此您的内循环将决定算法的复杂性。 因为 j 在第一次运行时会运行 'n' 次,在第二次运行时会运行 'n/3' 次等等。因此你的总复杂度可以计算为
n + n/3 + n/9 + n/27 + .......
导致 O(n)
【讨论】:
一些数学事实:1 + 1/3 + 1/9 + ... = 3/2
【参考方案4】:
所以这是一个很好的问题!这是一个需要更多思考才能分析的棘手问题。
正如其他一些答案中正确说明的那样,外循环:
for(int i = n; i > 0; i/=3)
将运行 log(n) 次。特别是 log_3(n) 次,但在大 O 表示法中,我们不经常担心基数,所以 log(n) 就可以了。
现在嵌套循环有点棘手:
for(int j = 0; j < i; j++)
乍一看,您可能会认为这是一个简单的 log(n) 循环,但让我们看的更远一些。 所以在第一次迭代中,这将运行 N 次,因为 i 的值为 n。下一次迭代它将运行 n/3 次。然后是 n/9、n/27、n/81 等......
如果我们对这个系列求和,很明显它的总数将小于 2n。 因此我们可以得出结论,该算法的复杂度为 O(n)。
【讨论】:
【参考方案5】:在你的代码 sn-p:
for (int i=0; i < n; i*=3)
for (int j=0; j < i; j++)
System.out.println("Hello");
i
中的外部循环是O(log_3(n))
,因为循环的每个增量都会将i
达到n
所需的接地量减少 3 倍。这是对数行为 (log_3
在这种情况下)。 j
中的内部循环简单地迭代了与i
的外部值相同的次数,因此我们可以将外部复杂度平方,得出:
O(log_3(n)^2)
【讨论】:
以上是关于这个算法的时间复杂度是多少的主要内容,如果未能解决你的问题,请参考以下文章