Come trovare la complessità temporale di un algoritmo


890

La domanda

Come trovare la complessità temporale di un algoritmo?

Cosa ho fatto prima di pubblicare una domanda su SO?

Ho attraversato questo , questo e molti altri link

Ma dove non sono riuscito a trovare una spiegazione chiara e diretta su come calcolare la complessità temporale.

Cosa so ?

Dì per un codice semplice come quello qui sotto:

char h = 'y'; // This will be executed 1 time
int abc = 0; // This will be executed 1 time

Dì per un ciclo come quello qui sotto:

for (int i = 0; i < N; i++) {        
    Console.Write('Hello World !');
}

int i = 0; Questo verrà eseguito solo una volta . Il tempo è effettivamente calcolato i=0e non la dichiarazione.

i <N; Questo verrà eseguito N + 1 volte

i ++; Questo verrà eseguito N volte

Quindi il numero di operazioni richieste da questo ciclo sono

{1+ (N + 1) + N} = 2N + 2

Nota: questo potrebbe ancora essere sbagliato, poiché non sono sicuro della mia comprensione sul calcolo della complessità temporale

Ciò che voglio sapere ?

Ok, quindi questi piccoli calcoli di base penso di saperlo, ma nella maggior parte dei casi ho visto la complessità temporale

O (N), O (n2), O (log n), O (n!) .... e molti altri ,

Qualcuno può aiutarmi a capire come si calcola la complessità temporale di un algoritmo? Sono sicuro che ci sono molti neofiti come me che vogliono saperlo.


138
Bonus per chi è interessato: The Big O Cheat Sheet bigocheatsheet.com
msanford

4
Dai un'occhiata a questo blog: mohalgorithmsorbit.blogspot.com . Copre algoritmi sia ricorsivi che (soprattutto) iterativi.
Mohamed Ennahdi El Idrissi

1
perché è Console.Write ('Hello World!'); non è un'istruzione automatica?
Chetan,


1
@Chetan Se intendi che dovresti considerare Console.Writequando calcoli la complessità, è vero, ma anche un po 'irrilevante in questo caso, poiché ciò cambia solo un fattore costante, che big-O ignora (vedi le risposte), quindi il risultato finale è ancora una complessità di O (N).
Bernhard Barker,

Risposte:


394

Come trovare la complessità temporale di un algoritmo

Si sommano quante istruzioni macchina eseguirà in funzione della dimensione del suo input, quindi si semplifica l'espressione al termine più grande (quando N è molto grande) e può includere qualsiasi fattore costante semplificante.

Ad esempio, vediamo come semplifichiamo 2N + 2le istruzioni della macchina per descriverlo come giusto O(N).

Perché rimuoviamo le due 2s?

Siamo interessati alle prestazioni dell'algoritmo quando N diventa grande.

Considera i due termini 2N e 2.

Qual è l'influenza relativa di questi due termini quando N diventa grande? Supponiamo che N sia un milione.

Quindi il primo termine è di 2 milioni e il secondo termine è solo 2.

Per questo motivo, eliminiamo tutti i termini tranne quelli più grandi per N. grande

Quindi, ora siamo passati da 2N + 2a 2N.

Tradizionalmente, siamo interessati solo a prestazioni fino a fattori costanti .

Ciò significa che non ci interessa davvero se c'è un multiplo costante di differenza nelle prestazioni quando N è grande. L'unità di 2N non è comunque ben definita in primo luogo. Quindi possiamo moltiplicare o dividere per un fattore costante per arrivare all'espressione più semplice.

Quindi 2Ndiventa giusto N.


53
ehi grazie per avermi fatto sapere "perché O (2N + 2) a O (N)" ha spiegato molto bene, ma questa era solo una parte della domanda più grande, volevo che qualcuno indicasse un collegamento a una risorsa nascosta o in generale volevo sapere come farti finire con complessità temporali come O (N), O (n2), O (log n), O (n!), ecc. So che potrei chiedere molto, ma posso ancora provare: {)
Yasser Shaikh

3
Bene, la complessità tra parentesi è quanto tempo impiega l'algoritmo, semplificato usando il metodo che ho spiegato. Scopriamo quanto tempo impiega l'algoritmo semplicemente sommando il numero di istruzioni macchina che eseguirà. Possiamo semplificare guardando solo i loop più occupati e dividendoli per fattori costanti, come ho spiegato.
Andrew Tomazos,

4
Dare un esempio in risposta avrebbe aiutato molto, per i futuri lettori. Il solo passaggio di un link per il quale devo registrarmi, non mi aiuta davvero quando voglio solo passare un po 'di testo ben spiegato.
bad_keypoints

2
Suggerirei di guardare i video del Dr. Naveen Garg (IIT Delhi Prof.) se vuoi avere una buona conoscenza di DS e complessità del tempo. Controlla il link. nptel.ac.in/courses/106102064
Rohit Bandil

2
(cont.) Questa gerarchia avrebbe un'altezza nell'ordine del log N. Per quanto riguarda O (N!) le mie analogie probabilmente non lo taglieranno, ma le permutazioni sono in quell'ordine - è proibitivamente ripido, più che in qualsiasi polinomio o esponenziale. Ce ne sono esattamente 10! secondi in sei settimane ma l'universo è meno di 20! secondi vecchi.
John P,

389

Questo è un articolo eccellente: http://www.daniweb.com/software-development/computer-science/threads/13488/time-complexity-of-algorithm

La risposta di seguito viene copiata dall'alto (nel caso in cui il collegamento eccellente vada a vuoto)

La metrica più comune per il calcolo della complessità temporale è la notazione O grande. Ciò rimuove tutti i fattori costanti in modo che il tempo di esecuzione possa essere stimato in relazione a N quando N si avvicina all'infinito. In generale puoi pensarlo in questo modo:

statement;

È costante. Il tempo di esecuzione dell'istruzione non cambierà rispetto a N.

for ( i = 0; i < N; i++ )
     statement;

È lineare. Il tempo di esecuzione del loop è direttamente proporzionale a N. Quando N raddoppia, anche il tempo di esecuzione.

for ( i = 0; i < N; i++ ) {
  for ( j = 0; j < N; j++ )
    statement;
}

È quadratico. Il tempo di esecuzione dei due loop è proporzionale al quadrato di N. Quando N raddoppia, il tempo di esecuzione aumenta di N * N.

while ( low <= high ) {
  mid = ( low + high ) / 2;
  if ( target < list[mid] )
    high = mid - 1;
  else if ( target > list[mid] )
    low = mid + 1;
  else break;
}

È logaritmico. Il tempo di esecuzione dell'algoritmo è proporzionale al numero di volte in cui N può essere diviso per 2. Ciò è dovuto al fatto che l'algoritmo divide l'area di lavoro a metà con ogni iterazione.

void quicksort ( int list[], int left, int right )
{
  int pivot = partition ( list, left, right );
  quicksort ( list, left, pivot - 1 );
  quicksort ( list, pivot + 1, right );
}

È N * log (N). Il tempo di esecuzione è costituito da N loop (iterativi o ricorsivi) che sono logaritmici, quindi l'algoritmo è una combinazione di lineare e logaritmica.

In generale, fare qualcosa con ogni oggetto in una dimensione è lineare, fare qualcosa con ogni oggetto in due dimensioni è quadratico e dividere l'area di lavoro a metà è logaritmico. Esistono altre misure Big O come radice cubica, esponenziale e quadrata, ma non sono così comuni. La notazione O grande è descritta come O ( <type> )dov'è <type>la misura. L'algoritmo quicksort verrebbe descritto come O ( N * log ( N ) ).

Si noti che nulla di tutto ciò ha preso in considerazione le misure migliori, medie e nel caso peggiore. Ognuno avrebbe la propria notazione Big O. Si noti inoltre che questa è una spiegazione MOLTO semplicistica. Big O è il più comune, ma è anche più complesso che ho mostrato. Ci sono anche altre notazioni come big omega, little oe big theta. Probabilmente non li incontrerai al di fuori di un corso di analisi dell'algoritmo. ;)


10
L' algoritmo quicksort nel peggiore dei casi ha un tempo di esecuzione di N ^ 2, sebbene questo comportamento sia raro.
nbro,

2
IIRC, little o e big omega sono usati per la complessità del caso migliore e medio (con big O è il caso peggiore), quindi "misure migliori, medie e peggiori. Ognuno avrebbe la propria notazione Big O". sarebbe errato. Esistono ancora più simboli con significati più specifici e CS non usa sempre il simbolo più appropriato. Sono venuto a imparare tutti questi con il nome Landau simboli tra l'altro. +1 comunque b / c migliore risposta.
hiergiltdiestfu,

@hiergiltdiestfu Big-O, Big-Omega, ecc. possono essere applicati a uno dei tempi di esecuzione migliori, medi o peggiori di un algoritmo. Come si collegano O e Ω al caso peggiore e migliore?
Bernhard Barker il

Inoltre, se qualcuno è alla ricerca di come calcolare grande O per qualsiasi metodo: stackoverflow.com/a/60354355/4260691
OhadM

Una delle migliori spiegazioni.
Shivaraj Patil,

172

Tratto da qui - Introduzione alla complessità temporale di un algoritmo

1. Introduzione

Nell'informatica, la complessità temporale di un algoritmo quantifica la quantità di tempo impiegata da un algoritmo per funzionare in funzione della lunghezza della stringa che rappresenta l'input.

2. Notazione O grande

La complessità temporale di un algoritmo è comunemente espressa usando una grande notazione O, che esclude coefficienti e termini di ordine inferiore. Se espresso in questo modo, si dice che la complessità temporale viene descritta asintoticamente, cioè quando la dimensione dell'ingresso va all'infinito.

Ad esempio, se il tempo richiesto da un algoritmo su tutti gli input di dimensione n è al massimo 5n 3 + 3n, la complessità del tempo asintotico è O (n 3 ). Ne parleremo più avanti.

Pochi altri esempi:

  • 1 = O (n)
  • n = O (n 2 )
  • log (n) = O (n)
  • 2 n + 1 = O (n)

3. O (1) Tempo costante:

Si dice che un algoritmo funzioni a tempo costante se richiede la stessa quantità di tempo indipendentemente dalle dimensioni dell'input.

Esempi:

  • array: accesso a qualsiasi elemento
  • stack di dimensioni fisse: metodi push e pop
  • coda a dimensione fissa: metodi di accodamento e dequeue

4. O (n) Tempo lineare

Si dice che un algoritmo funzioni in tempo lineare se la sua esecuzione temporale è direttamente proporzionale alla dimensione dell'input, cioè il tempo cresce linearmente all'aumentare della dimensione dell'input.

Considera i seguenti esempi, sotto sto cercando linearmente un elemento, questo ha una complessità temporale di O (n).

int find = 66;
var numbers = new int[] { 33, 435, 36, 37, 43, 45, 66, 656, 2232 };
for (int i = 0; i < numbers.Length - 1; i++)
{
    if(find == numbers[i])
    {
        return;
    }
}

Altri esempi:

  • Matrice: ricerca lineare, spostamento, ricerca minima ecc
  • ArrayList: contiene il metodo
  • Coda: contiene il metodo

5. O (log n) Tempo logaritmico:

Si dice che un algoritmo funzioni nel tempo logaritmico se la sua esecuzione temporale è proporzionale al logaritmo della dimensione di input.

Esempio: ricerca binaria

Richiama il gioco "venti domande": il compito è di indovinare il valore di un numero nascosto in un intervallo. Ogni volta che fai un'ipotesi, ti viene detto se la tua ipotesi è troppo alta o troppo bassa. Il gioco a venti domande implica una strategia che utilizza il tuo numero di ipotesi per dimezzare la dimensione dell'intervallo. Questo è un esempio del metodo generale di risoluzione dei problemi noto come ricerca binaria

6. O (n 2 ) Quadratic Time

Si dice che un algoritmo venga eseguito in un tempo quadratico se la sua esecuzione temporale è proporzionale al quadrato della dimensione di input.

Esempi:

7. Alcuni link utili


17
Nota: il primo collegamento è interrotto.
Ziezi,

2
O (n2) dovrebbe essere scritto O (n ^ 2) per evitare confusione.
Rizki Hadiaturrasyid,

100

Sebbene ci siano alcune buone risposte a questa domanda. Vorrei dare un'altra risposta qui con diversi esempi di loop.

  • O (n) : la complessità temporale di un loop viene considerata come O (n) se le variabili del loop vengono incrementate / decrementate di una quantità costante. Ad esempio le seguenti funzioni hanno una complessità temporale O (n) .

    // Here c is a positive integer constant   
    for (int i = 1; i <= n; i += c) {  
        // some O(1) expressions
    }
    
    for (int i = n; i > 0; i -= c) {
        // some O(1) expressions
    }
    
  • O (n ^ c) : la complessità temporale dei loop nidificati è uguale al numero di volte in cui viene eseguita l'istruzione più interna. Ad esempio i seguenti loop di esempio hanno una complessità temporale O (n ^ 2)

    for (int i = 1; i <=n; i += c) {
       for (int j = 1; j <=n; j += c) {
          // some O(1) expressions
       }
    }
    
    for (int i = n; i > 0; i += c) {
       for (int j = i+1; j <=n; j += c) {
          // some O(1) expressions
    }
    

    Ad esempio, Selezione ordinamento e Inserimento ordinamento hanno una complessità temporale O (n ^ 2) .

  • O (Logn) La complessità temporale di un loop è considerata come O (Logn) se le variabili del loop sono divise / moltiplicate per un importo costante.

    for (int i = 1; i <=n; i *= c) {
       // some O(1) expressions
    }
    for (int i = n; i > 0; i /= c) {
       // some O(1) expressions
    }
    

    Ad esempio, la ricerca binaria presenta una complessità temporale O (Logn) .

  • O (LogLogn) La complessità temporale di un loop viene considerata come O (LogLogn) se le variabili del loop vengono ridotte / aumentate esponenzialmente di una quantità costante.

    // Here c is a constant greater than 1   
    for (int i = 2; i <=n; i = pow(i, c)) { 
       // some O(1) expressions
    }
    //Here fun is sqrt or cuberoot or any other constant root
    for (int i = n; i > 0; i = fun(i)) { 
       // some O(1) expressions
    }
    

Un esempio di analisi della complessità temporale

int fun(int n)
{    
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j < n; j += i)
        {
            // Some O(1) task
        }
    }    
}

Analisi :

For i = 1, the inner loop is executed n times. For i = 2, the inner loop is executed approximately n/2 times. For i = 3, the inner loop is executed approximately n/3 times. For i = 4, the inner loop is executed approximately n/4 times. ……………………………………………………. For i = n, the inner loop is executed approximately n/n times.

Quindi la complessità temporale totale dell'algoritmo sopra è (n + n/2 + n/3 + … + n/n), che diventan * (1/1 + 1/2 + 1/3 + … + 1/n)

La cosa importante delle serie (1/1 + 1/2 + 1/3 + … + 1/n)è uguale a O (Logn) . Quindi la complessità temporale del codice sopra è O (nLogn) .


Rif: 1 2 3


1
@Simon, potresti per favore capire quale parte non è corretta?
zangw,

grazie per avermelo chiesto. Ho letto male il codice. Ho cancellato il mio commento Scusate!
Simon,

74

Complessità temporale con esempi

1 - Operazioni di base (aritmetica, confronti, accesso agli elementi dell'array, assegnazione): il tempo di esecuzione è sempre costante O (1)

Esempio :

read(x)                               // O(1)
a = 10;                               // O(1)
a = 1.000.000.000.000.000.000         // O(1)

2 - If then else statement: prendendo solo il tempo di esecuzione massimo da due o più istruzioni possibili.

Esempio:

age = read(x)                               // (1+1) = 2
if age < 17 then begin                      // 1
      status = "Not allowed!";              // 1
end else begin
      status = "Welcome! Please come in";   // 1
      visitors = visitors + 1;              // 1+1 = 2
end;

Quindi, la complessità del suddetto pseudo codice è T (n) = 2 + 1 + max (1, 1 + 2) = 6. Pertanto, il suo grande oh è ancora costante T (n) = O (1).

3 - Loop (per, mentre, ripeti): il tempo di esecuzione per questa istruzione è il numero di loop moltiplicato per il numero di operazioni all'interno di quel loop.

Esempio:

total = 0;                                  // 1
for i = 1 to n do begin                     // (1+1)*n = 2n
      total = total + i;                    // (1+1)*n = 2n
end;
writeln(total);                             // 1

Quindi, la sua complessità è T (n) = 1 + 4n + 1 = 4n + 2. Pertanto, T (n) = O (n).

4 - Nested Loop (looping all'interno di looping): poiché esiste almeno un looping all'interno del looping principale, il tempo di esecuzione di questa istruzione ha utilizzato O (n ^ 2) o O (n ^ 3).

Esempio:

for i = 1 to n do begin                     // (1+1)*n  = 2n
   for j = 1 to n do begin                  // (1+1)n*n = 2n^2
       x = x + 1;                           // (1+1)n*n = 2n^2
       print(x);                            // (n*n)    = n^2
   end;
end;

Tempo di esecuzione comune

Ci sono alcuni tempi di esecuzione comuni durante l'analisi di un algoritmo:

  1. O (1) - Tempo costante Il tempo costante indica che il tempo di esecuzione è costante, non è influenzato dalle dimensioni dell'ingresso .

  2. O (n) - Tempo lineare Quando un algoritmo accetta n dimensioni di input, eseguirà anche n operazioni.

  3. O (log n) - L'algoritmo del tempo logaritmico con tempo di esecuzione O (log n) è leggermente più veloce di O (n). Comunemente, l'algoritmo divide il problema in sotto-problemi con le stesse dimensioni. Esempio: algoritmo di ricerca binaria, algoritmo di conversione binaria.

  4. O (n log n) - Tempo lineare Questo tempo di esecuzione si trova spesso negli "algoritmi di divisione e conquista" che dividono il problema in sotto-problemi in modo ricorsivo e poi li uniscono in n tempo. Esempio: algoritmo Merge Sort.

  5. O (n 2 ) - Algoritmo Quadratic Time Look Bubble Sort!

  6. O (n 3 ) - Tempo cubico Ha lo stesso principio con O (n 2 ).

  7. O (2 n ) - Tempo esponenziale È molto lento poiché l'ingresso aumenta, se n = 1000.000, T (n) sarebbe 21000.000. L'algoritmo Brute Force ha questo tempo di esecuzione.

  8. O (n!) - Factorial Time THE SLOWEST !!! Esempio: Travel Salesman Problem (TSP)

Tratto da questo articolo . Molto ben spiegato dovrebbe dare una lettura.


Nel tuo secondo esempio, hai scritto visitors = visitors + 1è 1 + 1 = 2. Potresti spiegarmi perché l'hai fatto?
Sajib Acharya,

3
@Sajib Acharya Guardalo da destra a sinistra. Primo passaggio: calcolare visitors + 1 Secondo passaggio: assegnare il valore dal primo passaggio a visitors So, l'espressione sopra è formata da due istruzioni; primo passo + secondo passo => ​​1 + 1 = 2
Bozidar Sikanjic,

@nbro Perché è 1 + 1 inage = read(x) // (1+1) = 2
Humty

@BozidarSikanjic Perché è 1 + 1 inage = read(x) // (1+1) = 2
Humty

1
@Humty Controlla l'inizio di questa risposta: il read(x) // O(1) a = 10; // O(1)primo è la chiamata di funzione => O (1) ///// Il secondo è il compito, come ha detto nbro, ma 10 è costante, quindi il secondo è => O (1) ...
Bozidar Sikanjic

41

Quando analizzi il codice, devi analizzarlo riga per riga, contando ogni operazione / riconoscendo la complessità del tempo, alla fine, devi sommarlo per ottenere un quadro completo.

Ad esempio, puoi avere un ciclo semplice con complessità lineare , ma più avanti in quello stesso programma puoi avere un ciclo triplo con complessità cubica , quindi il tuo programma avrà complessità cubica . L'ordine delle funzioni di crescita entra in gioco proprio qui.

Diamo un'occhiata a quali sono le possibilità per la complessità temporale di un algoritmo, puoi vedere l'ordine di crescita che ho menzionato sopra:

  • Tempo costante ha un ordine di sviluppo 1, per esempio: a = b + c.

  • Tempo logaritmico ha un ordine di crescita LogN, di solito si verifica quando si divide qualcosa a metà (ricerca binaria, alberi, persino anelli) o si moltiplica qualcosa allo stesso modo.

  • Lineare ordine di crescita è N, ad esempio

    int p = 0;
    for (int i = 1; i < N; i++)
      p = p + 2;
    
  • linearitmico ordine di crescita , di n*logNsolito è presente negli algoritmi di divisione e conquista.

  • Cubo , ordine di crescita N^3, classico esempio è un triplo ciclo in cui si controllano tutte le terzine:

    int x = 0;
    for (int i = 0; i < N; i++)
       for (int j = 0; j < N; j++)
          for (int k = 0; k < N; k++)
              x = x + 2
    
  • Esponenziale , ordine di crescita2^N, di solito si verifica quando si esegue una ricerca esaustiva, ad esempio controllare sottoinsiemi di alcuni set.


Se così fosse, quale sarebbe la complessità? per (int i = 0; i <N; i ++) per (int j = i + 1; j <N; j ++) per (int k = j + 1; k <N; k ++) x = x + 2
user3156040

35

In parole povere, la complessità temporale è un modo per riassumere come il numero di operazioni o il tempo di esecuzione di un algoritmo aumenta all'aumentare della dimensione dell'input.

Come la maggior parte delle cose nella vita, un cocktail party può aiutarci a capire.

SU)

Quando arrivi alla festa, devi stringere la mano a tutti (fai un'operazione su ogni oggetto). All'aumentare del numero di partecipanti N, aumenta il tempo / lavoro necessario per stringere la mano a tuttiO(N) .

Perché O(N)e no cN?

C'è una variazione nella quantità di tempo necessaria per stringere la mano alle persone. Potresti calcolare la media e catturarlo in una costante c. Ma l'operazione fondamentale qui --- stringere la mano a tutti --- sarebbe sempre proporzionale O(N), qualunque cosa cfosse. Quando discutiamo se dovremmo andare ad un cocktail party, siamo spesso più interessati al fatto che dovremo incontrare tutti che nei minimi dettagli di come sono quegli incontri.

O (N ^ 2)

L'ospite del cocktail party vuole che tu faccia un gioco stupido in cui tutti incontrano tutti gli altri. Pertanto, devi incontrare N-1altre persone e, poiché la persona successiva ti ha già incontrato, devono incontrare altre N-2persone e così via. La somma di questa serie è x^2/2+x/2. Con l'aumentare del numero di partecipanti, il x^2termine diventa molto veloce , quindi lasciamo cadere tutto il resto.

O (N ^ 3)

Devi incontrare tutti gli altri e, durante ogni incontro, devi parlare di tutti gli altri nella stanza.

O (1)

L'host vuole annunciare qualcosa. Bevono un bicchiere di vino e parlano ad alta voce. Tutti li ascoltano. Si scopre che non importa quanti partecipanti ci siano, questa operazione richiede sempre lo stesso tempo.

O (registro N)

L'host ha presentato tutti al tavolo in ordine alfabetico. Dov'è Dan? Pensi che debba essere da qualche parte tra Adam e Mandy (certamente non tra Mandy e Zach!). Detto questo, è tra George e Mandy? No. Deve essere tra Adam e Fred, e tra Cindy e Fred. E così via ... possiamo localizzare in modo efficiente Dan guardando metà del set e poi metà di quel set. Alla fine, guardiamo O (log_2 N) individui.

O (N log N)

Puoi trovare dove sederti al tavolo usando l'algoritmo sopra. Se un gran numero di persone venisse al tavolo, uno alla volta, e tutti lo facessero, ciò richiederebbe O (N log N) . Questo risulta essere il tempo necessario per ordinare qualsiasi raccolta di articoli quando devono essere confrontati.

Caso migliore / peggiore

Arrivi alla festa e devi trovare Inigo: quanto tempo ci vorrà? Dipende da quando arrivi. Se tutti si aggirano, hai colpito il caso peggiore: ci vorrà del O(N)tempo. Tuttavia, se tutti sono seduti al tavolo, ci vorrà soloO(log N) tempo. O forse puoi sfruttare il potere urlante del bicchiere di vino dell'host e ci vorrà soloO(1) tempo.

Supponendo che l'host non sia disponibile, possiamo dire che l'algoritmo di individuazione di Inigo ha un limite inferiore di O(log N)e un limite superiore diO(N) , a seconda dello stato della parte al momento dell'arrivo.

Spazio e comunicazione

Le stesse idee possono essere applicate per comprendere come gli algoritmi usano lo spazio o la comunicazione.

Knuth ha scritto un bel articolo sull'ex intitolato "The Complexity of Songs" .

Teorema 2: Esistono canzoni arbitrariamente lunghe di complessità O (1).

PROVA: (grazie a Casey e alla Sunshine Band). Considera le canzoni Sk definite da (15), ma con

V_k = 'That's the way,' U 'I like it, ' U
U   = 'uh huh,' 'uh huh'

per tutti i k.


L'hai inchiodato, ora ogni volta che vado a un cocktail party cercherò inconsciamente di trovare la complessità temporale di eventi divertenti. Grazie per un esempio così divertente.
Sabunkar Tejas Sahailesh

5

So che questa domanda risale a molto tempo fa e ci sono alcune risposte eccellenti qui, tuttavia ho voluto condividere un altro po 'per le persone di mentalità matematica che inciamperanno in questo post. Il teorema del Maestro è un'altra cosa utile da sapere quando si studia la complessità. Non l'ho visto menzionato nelle altre risposte.


2

O (n) è una grande notazione O usata per scrivere la complessità temporale di un algoritmo. Quando sommi il numero di esecuzioni in un algoritmo otterrai un risultato come 2N + 2, in questa espressione N è il termine dominante (il termine che ha il maggiore effetto sull'espressione se il suo valore aumenta o diminuisce). Ora O (N) è la complessità temporale mentre N è il termine dominante. Esempio

For i= 1 to n;
  j= 0;
while(j<=n);
  j=j+1;

qui il numero totale di esecuzioni per loop interno è n + 1 e il numero totale di esecuzioni per loop esterno è n (n + 1) / 2, quindi il numero totale di esecuzioni per l'intero algoritmo è n + 1 + n (n + 1/2 ) = (n ^ 2 + 3n) / 2. qui n ^ 2 è il termine dominante, quindi la complessità temporale per questo algoritmo è O (n ^ 2)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.