Оптимизируйте эту функцию на Python, которая считает количество пар с суммой ноль:
def count_pairs(a):
cnt = 0
for i in range(len(a)):
for j in range(i+1, len(a)):
if a[i] + a[j] == 0:
cnt += 1
return cnt
предложите оптимизацию с анализом временной и памяти сложности, обсуждением крайних случаев и подходов с использованием хеш‑таблиц, сортировки или многопоточности

14 Окт в 14:55
4 +1
0
Ответы
1

Вот несколько быстрых и проверенных подходов с реализациями, сложностями и обсуждением краевых случаев.

1) Однопроходный хеш‑подсчёт (рекомендую — простая и быстрая)
Код:
def count_pairs(a):
from collections import defaultdict
cnt = 0
seen = defaultdict(int)
for x in a:
cnt += seen.get(-x, 0)
seen[x] += 1
return cnt

Анализ:

Время: (\mathcal{O}(n)) в среднем (один проход).Память: (\mathcal{O}(k)), где (k) — число уникальных элементов ((k \le n)).
Преимущества: один проход, корректно считает пары с нулями и дубликатами. Ограничения: деградация при плохих хешах теоретически, но в Python практически редко.

2) Подсчёт через Counter (симметричные пары)
Код:
def count_pairs_counter(a):
from collections import Counter
c = Counter(a)
cnt = c.get(0, 0) (c.get(0, 0) - 1) // 2 # пары нулей: C(n0,2)
for x in list(c):
if x > 0 and -x in c:
cnt += c[x] c[-x]
return cnt

Анализ:

Время: построение Counter (\mathcal{O}(n)), затем перебор ключей (\mathcal{O}(k)) => всего (\mathcal{O}(n)) в среднем.Память: (\mathcal{O}(k)).
Преимущество: явный контроль параллей, удобно если нужно знать частоты.

Формула для нулей: (\binom{n_0}{2} = \frac{n_0(n_0-1)}{2}).

3) Сортировка + два указателя (без доп. памяти, если сортировка in‑place)
Код:
def count_pairs_sorted(a):
a = sorted(a)
i, j = 0, len(a) - 1
cnt = 0
while i < j:
s = a[i] + a[j]
if s == 0:
if a[i] == a[j]:
k = j - i + 1
cnt += k (k - 1) // 2
break
left_val = a[i]; right_val = a[j]
left_count = right_count = 0
while i <= j and a[i] == left_val:
left_count += 1; i += 1
while j >= i and a[j] == right_val:
right_count += 1; j -= 1
cnt += left_count right_count
elif s < 0:
i += 1
else:
j -= 1
return cnt

Анализ:

Время: (\mathcal{O}(n \log n)) (сортировка) + (\mathcal{O}(n)) для двух указателей.Память: (\mathcal{O}(1)) дополнительной (или (\mathcal{O}(n)), если сортировка требует).
Преимущество: не нужно дополнительного хеша; полезно когда память критична и сортировка допустима.

4) Многопоточность/мультипроцессинг

В CPython многопоточность ограничена GIL — для CPU‑bound задач неэффективна. Используйте multiprocessing / ProcessPoolExecutor.Подход: разбить массив на чанки, в каждом чанке посчитать Counter (локально), затем объединить Counters в глобальный Counter и применить метод из (2). Временная сложность параллельно примерно (\mathcal{O}(n)) суммарно, но есть накладные расходы на сериализацию и объединение. Эффективно при очень больших данных и нескольких ядрах; требует больше памяти и IO.Альтернатива для потоков: map‑reduce стиль (счёт частот параллельно, затем редьюс).

Краевые случаи и замечания

Пустой список или один элемент: результат 0.Много одинаковых нулей: корректно считается формулой (\binom{n_0}{2}).Большие числа: в Python нет переполнения целых, но для float возможны проблемы с точностью (сравнение с нулём требует аккуратности).Если вход в виде строчек/нечисловых объектов — методы по‑прежнему работают при условии, что для элементов определены + и противоположный элемент (для хеша — хэшируемы).Для стриминговых данных: можно использовать однопроходный хеш‑подсчёт или внешнюю сортировку, если данные не помещаются в ОЗУ.

Рекомендация

Для общего случая — однопроходный хеш (первый вариант): прост, быстро и экономит время.Если память строго ограничена — используйте сортировку и два указателя.Для очень больших данных и многопроцессорных систем — разбить на чанки, строить Counters параллельно и объединять.

Если нужно, могу привести версию с multiprocessing для больших массивов или показать профилирование для вашего конкретного входа.

14 Окт в 16:53
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир