La mia risposta è O(n^2)
, ma credo che sia accurata e prende un leggermente diverso da approccio e sembra più facile da implementare.
Si supponga che il valore memorizzato nel nodo i
sia denotato da VALUE[i]
. La mia idea è di memorizzare su ogni nodo la somma dei valori sul percorso da root
a quel nodo. Quindi per ogni nodo i
, SUM[i]
è la somma del percorso da root
al nodo i
.
Quindi, per ogni coppia di nodi (i,j)
, trovare il loro antenato comune k
. Se SUM(i)+SUM(j)-SUM(k) = TARGET_SUM
, hai trovato una risposta.
Questo è O(n^2)
poiché stiamo eseguendo il ciclo su tutte le coppie di nodi. Anche se, mi piacerebbe poter capire un modo migliore di scegliere solo tutte le coppie.
Potremmo ottimizzarlo un po 'scartando sottotasti in cui il value
del nodo radicato nella sottostruttura è maggiore di TARGET_SUM
. Eventuali ulteriori ottimizzazioni sono i benvenuti :)
psuedocodarlo:
# Skipping code for storing sum of values from root to each node i in SUM[i]
for i in nodes:
for j in nodes:
k = common_ancestor(i,j)
if (SUM[i] + SUM[j] - SUM[k] == TARGET_SUM):
print_path(i,k,j)
Funzione common_ancestor
è un problema abbastanza standard per un albero binario di ricerca. Psuedocode (dalla memoria, si spera non ci siano errori!):
sub common_ancestor (i, j):
parent_i = parent(i)
# Go up the parent chain until parent's value is out of the range.
# That's a red flag.
while(VAL[i] <= VAL[parent_i] <= VAL[j]) :
last_parent = parent_i
parent_i = parent(i)
if (parent_i == NULL): # root node
break
return last_parent
@ il root è 2, il sottoalbero sinistro è 1, e il sottoalbero destro è 3 nell'esempio pubblicato – TimeToCodeTheRoad
Preferisco utilizzare un grafico bidirezionale (con connessioni di nodo limitato) a tale scopo. Gli alberi bin (almeno per me) implicano una direzione fissa, unica. – fjdumont
Come aiuta? – marcog