web-dev-qa-db-fra.com

Pourquoi la complexité Big-O de cet algorithme O (n ^ 2)?

Je sais que la complexité big-O de cet algorithme est O(n^2), mais je ne comprends pas pourquoi.

int sum = 0; 
int i = 1; j = n * n; 
while (i++ < j--) 
  sum++;

Même si nous définissons j = n * n au début, nous incrémentons i et décrémentons j à chaque itération, donc le nombre d'itérations résultant ne devrait-il pas être bien inférieur à n*n?

54
Omar N

À chaque itération, vous incrémentez i et décrémentez j ce qui équivaut à simplement incrémenter i de 2. Par conséquent, le nombre total d'itérations est n ^ 2/2 et c'est toujours O (n ^ 2).

114
Miljen Mikic

la complexité big-O ignore les coefficients. Par exemple: O(n), O(2n) et O(1000n) sont tous identiques O(n) durée d'exécution. De même, O(n^2) et O(0.5n^2) sont tous deux O(n^2) temps d'exécution.

Dans votre situation, vous incrémentez essentiellement votre compteur de boucles de 2 à chaque fois dans votre boucle (puisque j-- A le même effet que i++). Donc, votre temps d'exécution est O(0.5n^2), mais c'est la même chose que O(n^2) lorsque vous supprimez le coefficient.

53
Ben Rubin

Vous aurez exactement n*n/2 Itérations de boucle (ou (n*n-1)/2 Si n est impair). Dans la grande notation O, nous avons O((n*n-1)/2) = O(n*n/2) = O(n*n) parce que les facteurs constants "ne comptent pas".

11
m3tikn0b

Votre algorithme est équivalent à

while (i += 2 < n*n) 
  ...

qui est O(n^2/2) qui est identique à O(n^2) parce que la grande complexité O ne se soucie pas des constantes.

10
Salvador Dali

Oui, cet algorithme est O (n ^ 2).

Pour calculer la complexité, nous avons un tableau des complexités:

O(1) O(log n) O(n) O(n log n)
O (n²) O (n ^ a) O (a ^ n) O (n!)

Chaque ligne représente un ensemble d'algorithmes. Un ensemble d'algorithmes qui est en O (1), aussi en O (n), et O (n ^ 2), etc. Mais pas à l'inverse. Ainsi, votre algorithme réalise n * n/2 phrases.

O(n) < O(nlogn) < O(n*n/2) < O(n²)

Ainsi, l'ensemble des algorithmes qui incluent la complexité de votre algorithme, est O (n²), car O(n) et O(nlogn) sont plus petits) .

Par exemple: À n = 100, somme = 5000. => 100 O(n) <200 O (n · logn) <5000 (n * n/2) <10000 (n ^ 2)

Je suis désolé pour mon anglais.

Soit m le nombre d'itérations prises. Alors,

i + m = n ^ 2 - m

qui donne,

m = (n ^ 2-i)/2

En notation Big-O, cela implique une complexité de O (n ^ 2).

4
Ujjwal Aryan

Même si nous fixons j = n * n au début, nous incrémentons i et décrémentons j à chaque itération, donc le nombre d'itérations résultant ne devrait-il pas être bien inférieur à n * n?

Oui! C'est pourquoi c'est O (n ^ 2). Par la même logique, c'est beaucoup moins que n * n * n, ce qui en fait O (n ^ 3). C'est même O (6 ^ n), par une logique similaire.

big-O vous donne des informations sur les limites supérieures.

Je crois que vous essayez de vous demander pourquoi la complexité est thêta (n) ou oméga (n), mais si vous essayez simplement de comprendre ce qu'est le big-O, vous vraiment devez comprendre que cela donne bornes supérieures sur les fonctions avant tout.

0
djechlin