简体   繁体   English

这个算法的时间复杂度是多少

[英]What will be the time complexity of this algorithm

I am very new to competitive programming and to Big O notation.我对竞争性编程和大 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");
       }
   }
}

This is the algorithm.这就是算法。 As far as i know about time complexity.It defines how run time gets affected from number of inputs.据我所知时间复杂度。它定义了运行时间如何受到输入数量的影响。

So here if we take a example if 'n' is 10. The outer loop runs log n times and the inner loop runs 'i' times.所以在这里如果我们举一个例子,如果'n'是10。外部循环运行log n次,内部循环运行'i'次。

the inner loop runs relatively to 'i' not 'n'.内部循环相对于“i”而不是“n”运行。 So im a bit confused here as to how the time complexity is calculated.所以我对如何计算时间复杂度有点困惑。 I think it is O(log n).Please correct me if i am wrong.我认为它是 O(log n)。如果我错了,请纠正我。

Will it be O(log n) or O (n log n) or (n^2).它是 O(log n) 还是 O (n log n) 或 (n^2)。 Please help me out with this.这个你能帮我吗。 Thank you.谢谢你。

I will try to explain it in the simplest term possible我会尽量用最简单的术语来解释它

The outer loop will simply run log(n) with base 3 times.外部循环将简单地以 3 次为底运行 log(n)。

Since, i is decreasing by factor of 3 every time.因为,我每次都减少 3 倍。 The total work done is equal to:完成的总功等于:

n + n/3 + n/9 + n/27 +.... n/(3^log(n)) n + n/3 + n/9 + n/27 +.... n/(3^log(n))

since, n/3 +... + n/(3^log(n)) will always be less than n因为,n/3 +... + n/(3^log(n)) 将始终小于 n

for eg let n = 100 then, 100 + 100/3 + 100/9 + 100/27 +... = 100 + (33.3 + 11.11 + 3.7 +...)例如让 n = 100 那么,100 + 100/3 + 100/9 + 100/27 +... = 100 + (33.3 + 11.11 + 3.7 +...)

we can clearly see the terms in the bracket will always be less than 100我们可以清楚地看到括号中的项总是小于 100

The total time complexity of the overall solution will be O(n).整个解决方案的总时间复杂度将为 O(n)。

Actually it will never terminate cause i=0 and update is i *= 3 so i will stay 0 so we can say O(+oo)实际上它永远不会终止,因为i=0并且更新是i *= 3所以i会保持0所以我们可以说O(+oo)

assuming you meant for(int i =1... instead, then its O(n) :假设你的意思是for(int i =1...相反,那么它的O(n)

  • Outer loop is clearly O(log_3 n) cause we keep multiplying by 3外循环显然是O(log_3 n)因为我们一直乘以 3
  • Inner loop will get executed O(log_3 n) times with iteration count of (1 + 3 + 9 + 27 +... + 3^log_3(n)) which is clearly a geometric progression, solving which gives us approx 3^log_3(n)) which according to log rules gives n so this loop takes O(n) for all iterations, so total complexity is O(n)内部循环将执行O(log_3 n)次,迭代计数为(1 + 3 + 9 + 27 +... + 3^log_3(n)) ,这显然是一个几何级数,求解给我们大约3^log_3(n))根据对数规则给出n所以这个循环对所有迭代都需要O(n) ,所以总复杂度是O(n)

for your code:对于您的代码:

for(int i = n; i > 0; i/=3){
   for(int j = 0; j < i; j++){
       System.out.println("Hello");
   }

} }

Inner loop variable j is dependent on outer loop variable i, so your inner loop will be the one which will decide the complexity for your algorithm.内循环变量 j 取决于外循环变量 i,因此您的内循环将决定算法的复杂性。 since j will run 'n' times in first run, 'n/3' times in second run and so on.. therefore your total complexity can be calculated as因为 j 将在第一次运行中运行“n”次,在第二次运行中运行“n/3”次等等..因此您的总复杂度可以计算为

n + n/3 + n/9 + n/27 +....... n + n/3 + n/9 + n/27 +.......

resulting in O(n)导致 O(n)

So this is a great question.所以这是一个很好的问题。 It's a tricky one that takes a little more thinking to analyse.这是一个棘手的问题,需要更多的思考来分析。

As correctly stated in some of the other answers, the outer loop:正如其他一些答案中正确说明的那样,外循环:

for(int i = n; i > 0; i/=3)

Will run log(n) times.将运行 log(n) 次。 Specifically log_3(n) times but in big O notation we don't often worry about the base so log(n) will be fine.特别是 log_3(n) 次,但在大 O 表示法中,我们不经常担心基数,所以 log(n) 会很好。

Now the nested loop is a bit trickier:现在嵌套循环有点棘手:

for(int j = 0; j < i; j++){

On first glance you may think this is a simple log(n) loop but lets look a little further.乍一看,您可能会认为这是一个简单的 log(n) 循环,但让我们看的更远一些。 So on the first iteration this will run N times since the value of i will be n.所以在第一次迭代中,这将运行 N 次,因为 i 的值为 n。 Next iteration it will be run n/3 times.下一次迭代它将运行 n/3 次。 Then n/9, n/27, n/81 etc....然后 n/9、n/27、n/81 等......

If we sum this series, it is clear to see it will total less than 2n.如果我们对这个系列求和,很明显它的总数将小于 2n。 Therefore we can conclude this algorithm has a complexity of O(n).因此,我们可以得出结论,该算法的复杂度为 O(n)。

In your code snippet:在您的代码段中:

for (int i=0; i < n; i*=3) { 
    for (int j=0; j < i; j++) {
        System.out.println("Hello");
    }
}

The outer loop in i is O(log_3(n)) , because each increment of the loop decreases the amount of ground needed for i to reach n by a factor of 3. This is logarithmic behavior ( log_3 in this case). i中的外部循环是O(log_3(n)) ,因为循环的每个增量都会将i达到n所需的接地量减少 3 倍。这是对数行为(在这种情况下为log_3 )。 The inner loop in j simply iterates the same number of times as whatever the outer value of i might be, so we can just square the outer complexity, to arrive at: j中的内部循环简单地迭代与i的外部值相同的次数,因此我们可以将外部复杂度平方,得到:

O(log_3(n)^2)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM