La complessità temporale di un ciclo while con tre puntatori diversi da 3 annidati per cicli?

1

Questo programma (scritto in ruby) trova i 3 numeri più grandi in un array (senza ordinare l'array). Ha un ciclo while con tre puntatori. Il mio istinto di pugno, dato che c'è un solo ciclo, è che questa soluzione è O (n). Ma i puntatori j e k vengono ripristinati quando raggiungono n, il che sembra lo stesso di usare 3 per cicli, quindi è O (n³)?

def greatest_of_3_with_ptrs(a)
  greatest = 0
  greatest_tuple = nil
  i,j,k=0,1,2
  n = a.length-1
  while( true) do
    sum = a[i]+a[j]+a[k]
    if sum > greatest then
      greatest = sum 
      greatest_tuple =[a[i],a[j],a[k]]
    end  
    sum = 0
    if k == n then
      j=j+1
      k=j+1
    else
      k+=1  
    end
    if j == n then
      i=i+1
      j=i+1
      k=j+1
    end
    break if k > n || j > n || i==n
  end
  { greatest_tuple: greatest_tuple, greatest: greatest }
end

a =[10,-1,4,2,5,3,0]
expected = 19
print greatest_of_3_ptrs(a)[:greatest] #> 19
print greatest_of_3_ptrs(a)[:greatest_tuple] #> [10,4,5]

Nota: sono a conoscenza della soluzione O (n), non è una mia domanda

def greatest(a)
  max_1,max_2,max_3 = a[0],a[1],a[2]  
  for i in 3..a.length-1
    if a[i] > max_1 then
      max_1 = a[i]
    elsif a[i] > max_2 then
      max_2 = a[i]
    elsif a[i] > max_3 then
      max_3 = a[i]
    end      
  end
  [max_1,max_2,max_3]
end
    
posta archie 19.07.2015 - 23:58
fonte

2 risposte

3

Se sembra una soluzione O (n³). Il tuo istinto è corretto: resettando le variabili che stai eseguendo in loop. Nota: se consideriamo solo l'istruzione loop, penseremmo erroneamente che fosse O (∞).

Tuttavia il problema è O (n). Quindi puoi fare di meglio.

    
risposta data 20.07.2015 - 00:06
fonte
0

Hai assolutamente ragione. La funzione prova tutte le possibili combinazioni di elementi dall'array. In questo caso, è O (n³) e sarebbe di una potenza ancora maggiore, se si scrivesse una funzione simile per i più grandi 4, 5, .. elementi. La soluzione migliore per uno di questi problemi dovrebbe essere dell'ordine O (n).

Voglio solo ricordare che nel tuo esempio per una soluzione O (n) hai omesso il "down-shift" quando sostituisci un valore:

def greatest(a)
  max_1,max_2,max_3 = a[0..2].sort.reverse #changed
  for i in 3..a.length-1
    if a[i] > max_1 then
      max_3 = max_2 #new
      max_2 = max_1 #new
      max_1 = a[i]
    elsif a[i] > max_2 then
      max_3 = max_2 #new
      max_2 = a[i]
    elsif a[i] > max_3 then
      max_3 = a[i]
    end      
  end
  [max_1,max_2,max_3]
end
    
risposta data 04.09.2015 - 17:47
fonte

Leggi altre domande sui tag