2012-09-05 18 views
8

En el libro Programando entrevistas expuestas dice que la complejidad del programa a continuación es O (N), pero no entiendo cómo esto es posible. ¿Alguien puede explicar por qué es esto?¿Cuál es la complejidad de este código cuyo ciclo anidado repetidamente dobla su contador?

int var = 2; 
for (int i = 0; i < N; i++) { 
    for (int j = i+1; j < N; j *= 2) { 
     var += var; 
    } 
} 
+1

* "Se dice" * ¿Qué dice? Cuéntanos qué es lo que estás asumiendo aquí. – dmckee

+0

Hice la edición, disculpe la vaguedad –

+0

Esta estructura de bucle está muy relacionada con la del algoritmo de heapify y el análisis será muy similar. – templatetypedef

Respuesta

15

Necesita un poco de matemática para ver eso. El ciclo interno itera Θ(1 + log [N/(i+1)]) veces (el 1 + es necesario ya que para i >= N/2, [N/(i+1)] = 1 y el logaritmo es 0, pero el ciclo se repite una vez). j toma los valores (i+1)*2^k hasta que es al menos tan grande como N, y

(i+1)*2^k >= N <=> 2^k >= N/(i+1) <=> k >= log_2 (N/(i+1)) 

usando la división matemática. Por lo tanto, la actualización j *= 2 se llama ceiling(log_2 (N/(i+1))) veces y la condición se marca 1 + ceiling(log_2 (N/(i+1))) veces. Por lo tanto, podemos escribir el trabajo total

N-1         N 
∑ (1 + log (N/(i+1)) = N + N*log N - ∑ log j 
i=0         j=1 
         = N + N*log N - log N! 

Ahora, Stirling's formula nos dice

log N! = N*log N - N + O(log N) 

así encontramos el trabajo total realizado es de hecho O(N).

+0

felicitaciones por las ecuaciones ASCII/art – meowgoesthedog

1

@La respuesta de Daniel Fischer es correcta.

me gustaría añadir el hecho de que la hora exacta ejecución de este algoritmo es el siguiente:

enter image description here

Lo que significa:

enter image description here

4

bucle externo se ejecuta n veces. Ahora todo depende del bucle interno.
El bucle interno ahora es complicado.

Sigamos:

i=0 --> j=1    ---> log(n) iterations 
... 
... 
i=(n/2)-1 --> j=n/2  ---> 1 iteration. 
i=(n/2) --> j=(n/2)+1 --->1 iteration. 

i > (n/2)   ---> 1 iteration 
(n/2)-1 >= i > (n/4) ---> 2 iterations 
(n/4) >= i > (n/8) ---> 3 iterations 
(n/8) >= i > (n/16) ---> 4 iterations 
(n/16) >= i > (n/32) ---> 5 iterations 

(n/2)*1 + (n/4)*2 + (n/8)*3 + (n/16)*4 + ... + [n/(2^i)]*i 

    N-1         
n*∑ [i/(2^i)] =< 2*n 
    i=0 

--> O(n) 
+0

Quizás quiso decir 'j' en lugar de' i' en la segunda casilla? – meowgoesthedog

+0

@meowgoesthedog, no. Quise decir 'i', cuando el bucle externo está en estos rangos, a j se le asignará' 1 2 3 4 5 ... 'valores diferentes (número de iteraciones) Por cierto, buena ganancia de reputación :). Hace algunos días tenías 800 ~ –

+0

Pero 'j' es la variable que crece exponencialmente, no linealmente como' i'? Y no creo que el número de iteraciones aumente linealmente como lo dijiste. – meowgoesthedog

Cuestiones relacionadas