我对竞争性编程和Big 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。 外循环运行n次,内循环运行“ i”次。
内部循环相对于“ i”而不是“ n”运行。 因此,对于时间复杂度的计算方式,我有点困惑。 我认为是O(log n)。如果我错了,请纠正我。
是O(log n)还是O(n log n)或(n ^ 2)。 这个你能帮我吗。 谢谢。
答案 0 :(得分:5)
我将尝试用最简单的术语进行解释
外部循环将简单地以3为底运行log(n)。
因此,我每次都会减少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)。
答案 1 :(得分:1)
实际上,它永远不会终止,原因是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))
,根据对数规则得出{{1} },因此此循环的所有迭代都需要n
,因此总复杂度为O(n)
答案 2 :(得分:1)
输入您的代码:
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)
答案 3 :(得分:1)
所以这是一个很好的问题!这是一个棘手的问题,需要更多的思考才能进行分析。
在其他一些答案中正确指出的是外循环:
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)循环,但让我们进一步了解一下。 因此,在第一次迭代中,由于i的值为n,因此它将运行N次。下次迭代将运行n / 3次。然后是n / 9,n / 27,n / 81等...
如果我们对该系列求和,很明显它的总和小于2n。 因此可以断定该算法的复杂度为O(n)。
答案 4 :(得分:0)
在您的代码段中:
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)