Я недавно пытался решить какую-то задачу в Python, и я нашел решение, которое, кажется, имеет сложность O (n log n) , но я считаю, что оно очень неэффективно для некоторых входных данных (например, первый параметр 0
и pairs
- очень длинный список нулей).
Он также имеет три уровня циклов for
.Я верю, что это можно оптимизировать, но в настоящий момент я не могу оптимизировать его больше, я, вероятно, просто упускаю что-то очевидное;)
Итак, в принципе, проблема заключается в следующем:
При заданном списке целых чисел (values
) функция должна возвращать количество пар индексов, которые соответствуют следующим критериям:
- позволяет предположить, что единичная пара индексов является кортежем типа
(index1, index2)
, - , тогда
values[index1] == complementary_diff - values[index2]
равно true,
Пример : если задан список типа [1, 3, -4, 0, -3, 5]
как values
и 1
как complementary_diff
, функция должна возвращать 4
(это длина следующего списка пар индексов: [(0, 3), (2, 5), (3, 0), (5, 2)]
).
Это то, что я до сих пор, она должна прекрасно работать большинствовремя, но - как я уже сказал - в некоторых случаях он может работать очень медленно, несмотря на приблизительную сложность O (n log n) (похоже, пессимистическая сложность равна 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)
Для данного примера он ведет себя так:
>>> complementary_pairs_number(1, [1, 3, -4, 0, -3, 5])
4
Если выо том, как код может быть «сплющен» или «упрощен», пожалуйста, дайте мне знать.
Я не уверен, что лучший способ - просто проверить complementary_diff == 0
и т. д. - если вы так думаете, пожалуйста,дайте мне знать.
РЕДАКТИРОВАТЬ: Я исправил пример (спасибо, unutbu!).