Recentemente ho cercato di risolvere alcune attività in Python e ho trovato la soluzione che sembra avere la complessità di O (n log n), ma io ci credo è molto inefficiente per alcuni input (ad esempio il primo parametro è 0
e pairs
è un elenco molto lungo di zeri).Appiattimento di cicli annidati/complessità decrescente - algoritmo di conteggio coppie complementari
Ha anche tre livelli di loop for
. Credo che può essere ottimizzato, ma al momento non posso ottimizzare più, io sono probabilmente solo manca qualcosa di ovvio;)
Quindi, in sostanza, il problema è il seguente:
lista Data di numeri interi (
values
), la funzione deve restituire il numero di coppie di indici che soddisfano i seguenti criteri:
- Assumiamo pair indice unico è una tupla come
(index1, index2)
,- poi
values[index1] == complementary_diff - values[index2]
i s vero,Esempio: Se dato una lista come
[1, 3, -4, 0, -3, 5]
comevalues
e1
comecomplementary_diff
, la funzione dovrebbe restituire4
(che è la lunghezza della seguente lista di coppie di indici:[(0, 3), (2, 5), (3, 0), (5, 2)]
).
Questo è ciò che ho finora, dovrebbe funzionare perfettamente la maggior parte del tempo, ma - come ho detto - in alcuni casi potrebbe funzionare molto lentamente, nonostante il ravvicinamento della sua complessità O (n log n (sembra che la complessità pessimistica sia O (n^2)).
def complementary_pairs_number (complementary_diff, values):
value_key = {} # dictionary storing indexes indexed by values
for index, item in enumerate(values):
try:
value_key[item].append(index)
except (KeyError,): # the item has not been found in value_key's keys
value_key[item] = [index]
key_pairs = set() # key pairs are unique by nature
for pos_value in value_key: # iterate through keys of value_key dictionary
sym_value = complementary_diff - pos_value
if sym_value in value_key: # checks if the symmetric value has been found
for i1 in value_key[pos_value]: # iterate through pos_values' indexes
for i2 in value_key[sym_value]: # as above, through sym_values
# add indexes' pairs or ignore if already added to the set
key_pairs.add((i1, i2))
key_pairs.add((i2, i1))
return len(key_pairs)
Per il nostro esempio si comporta così:
>>> complementary_pairs_number(1, [1, 3, -4, 0, -3, 5])
4
Se si vede come il codice potrebbe essere "appiattita" o "semplificata", per favore fatemelo sapere.
Non sono sicuro che la semplice ricerca di complementary_diff == 0
ecc. Sia l'approccio migliore. Se lo ritieni opportuno, faccelo sapere.
MODIFICA: Ho corretto l'esempio (grazie, unutbu!).
Se qualcosa non è abbastanza chiaro o se hai qualche domanda, per favore chiedi loro - forse potrei migliorare la mia domanda :) – Tadeck
Penso che il 'key_pairs' nel tuo esempio sia' set ([(3, 0), (0 , 3), (5, 2), (2, 5)]) '(notare il 5, non 4). Sì? – unutbu
@unutbu: hai ragione, grazie! Ho modificato la domanda. – Tadeck