确定代码段的时间复杂度
Posted
技术标签:
【中文标题】确定代码段的时间复杂度【英文标题】:Determining the time complexity for code segments [duplicate] 【发布时间】:2017-09-07 20:53:57 【问题描述】:以下每个代码段的时间复杂度是多少?
1. int i, j, y=0, s=0;
for ( j = 1; j <= n; j ++)
y=y+j;
for ( i = 1; i <= y; i ++)
s++;
我的答案是 O(2n),因为它遍历每个循环 n 次并且有两个循环
2. function (n)
while (n > 1)
n = n/3 ;
我对此的回答是 n^(1/3),因为 n 每次都会变成它的三分之一
3. function (n)
int i, j, k ;
for ( i = n/2; i <= n; i ++ ) //n/2?
for ( j = 1; j <= n; j = 2*j ) //logn
for ( k = 1; k <= n; k = 2*k ) //logn
cout << ”COSC 2437.201, 301” << endl;
我说这个问题的答案是 O(log2*log2n*n/2) 但我对第一个 for 循环感到很困惑。循环只需要迭代 n 次的一半,所以它是 n/2 正确的吗?谢谢大家的帮助。
【问题讨论】:
首先,O(2n)
只是 O(n)
- 这是问题 1 的错误答案。
第一个 for 循环究竟是什么让你感到困惑?
第一段怎么可能是 O(n) 之外的任何东西?对于第一个循环,循环只需要迭代 n 次的一半,所以它会是 n/2 正确吗?
第二个循环呢?这取决于第一个循环后y
的值,对吧?那会是什么?
"n^(1/3) 因为 n 每次都变成它的三分之一" 不合逻辑。
【参考方案1】:
问题 1
第一个循环是O(n)
,因为它运行n
次。 然而,第二个循环执行y
次,而不是n
- 所以总运行时间不是“2n
”
在第一个循环结束时,y
的值为:
因此第二个循环占主导地位,因为它是O(n^2)
,因此也是整体复杂度。
问题 3
这个答案是正确的(但同样,在 O 表示法中删除 2
的因子)。
但是,您必须小心不要天真地将循环的复杂性相乘,因为内部循环的边界可能取决于外部循环的自发值。
问题 2
这不是O(n^(1/3))
!你的推理是错误的。
如果仔细观察这个循环,它实际上类似于问题 3 中的内部循环的 reverse:
在第三季度,k
的值从 1 开始,每次乘以 2,直到达到 n
在第二季度,n
的值每次除以 3,直到达到 1。
因此他们都采取O(log n)
步骤。
(顺便说一句,O(n^(1/3))
循环看起来像这样:)
for (int i = 1; i*i*i <= n; i++)
/* ... */
【讨论】:
帮别人做作业是可以的,但不要为他们做。 @n.m.你是对的;我认为 OP 可能需要更多的解释,而不是挤进评论中 我的意思是我不只是想得到答案。您的回答是唯一真正帮助我了解发生了什么的答案。谢谢。以上是关于确定代码段的时间复杂度的主要内容,如果未能解决你的问题,请参考以下文章