web-dev-qa-db-fra.com

Quel est le Big-O d'une boucle imbriquée, où le nombre d'itérations dans la boucle interne est déterminé par l'itération actuelle de la boucle externe?

Quelle est la complexité temporelle Big-O des boucles imbriquées suivantes:

for(int i = 0; i < N; i++) 
{
    for(int j = i + 1; j < N; j++)
    {
        System.out.println("i = " + i + " j = " + j);
    }

}

Serait-ce O (N ^ 2) encore? 

37
mmcdole

Oui, c'est toujours O (n ^ 2), il a un facteur constant plus petit, mais cela n'affecte pas la notation O.

33
Alex Gaynor

Oui. Rappelons la définition de Big-O: O(f(n)) par définition, indique que le temps d'exécution T(n) kf (n) pour une constante k . Dans ce cas, le nombre d'étapes sera (n-1) + (n-2) + ... + 0 , ce qui correspond à la somme de 0 à n-1; c'est 

T (n) = (n-1) ((n-1) +1)/2

Réorganisez cela et vous pouvez voir que T(n) sera toujours ≤ 1/2 (n²); par la définition, donc T(n) = O (n²) .

25
Charlie Martin

C'est N carré si vous ignorez le System.out.println. Si vous supposez que le temps pris par cela sera linéaire dans sa sortie (ce qui pourrait bien ne pas l'être, bien sûr), je suppose que vous vous retrouvez avec O ((N ^ 2) * log N).

Je mentionne ceci pour ne pas être pointilleux, mais juste pour souligner que vous ne devez pas simplement prendre en compte les boucles évidentes lorsque vous travaillez sur la complexité - vous devez également regarder la complexité de ce que vous appelez.

12
Jon Skeet

Oui, ce serait N carré. Le nombre réel d’étapes serait la somme de 1 à N, qui est 0,5 * (N - 1) ^ 2, si je ne me trompe pas. Big O ne prend en compte que l’exposant le plus élevé et aucune constante, ce qui fait que N est toujours au carré.

3
Charles Graham

Si vous aviez N = 10, vos itérations seraient: 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1. (Ceci est: dix itérations plus neuf itérations plus huit itérations ... etc.).

Maintenant, vous devez trouver dans l'addition combien de fois vous pouvez obtenir un N (10 dans l'exemple): 

1: (10), 2: (9 + 1), 3: (8 + 2), 4: (7 + 3), 5: (6 + 4). Ce qui est 5 fois ... et repose 5 itérations.

Maintenant vous savez que vous avez cinq dizaines + 5:

10 (5) + 5

En termes de f(n) (ou N), on peut facilement voir que ce serait:

f (n) = n(n/2) + n/2 = (n ^ 2)/2 + n/2 = (n ^ 2 + n)/2 ... c'est exactement la complexité de ces boucles imbriquées.

Mais, en considérant le comportement asymptotique de Big O, nous pouvons nous débarrasser des valeurs moins significatives de f (n), qui sont le n simple et le dénominateur.

Résultat: O (n ^ 2)

3
Jorge Gil

AFAIL, le fait de commencer à partir d’une boucle interne à travers une autre est un moyen adéquat de calculer la complexité des boucles imbriquées .  enter image description here

0
snr