Заметьте, что если A[i]^A[j] == x
, это означает, что A[i]^x == A[j]
и A[j]^x == A[i]
.
Таким образом, решение O (n) состоит в том, чтобы перебрать ассоциированную карту (dict
), где каждый ключ - это элемент из A
, а каждое значение - это соответствующий счетчик элемента. Затем для каждого элемента рассчитайте A[i]^x
и посмотрите, есть ли A[i]^x
на карте. Если на карте равно , это означает, что A[i]^A[j] == x
для некоторых j
. Поскольку у нас есть карта с количеством элементов, равным A[j]
, общее количество пар будет num_Ai * num_Aj
. Обратите внимание, что каждый элемент будет учитываться дважды, так как XOR является коммутативным (т.е. A[i]^A[j] == A[j]^A[i]
), поэтому мы должны разделить окончательный счет на 2, так как мы дважды посчитали каждую пару.
def create_count_map(lst):
result = {}
for item in lst:
if item in result:
result[item] += 1
else:
result[item] = 1
return result
def get_count(lst, x):
count_map = create_count_map(lst)
total_pairs = 0
for item in count_map:
xor_res = item ^ x
if xor_res in count_map:
total_pairs += count_map[xor_res] * count_map[item]
return total_pairs // 2
print(get_count([3, 6, 8, 10, 15, 50], 5))
print(get_count([1, 3, 1, 3, 1], 2))
выходы
2
6
по желанию.
Почему это O (n)?
Преобразование list
в dict
s.t. дикт содержит количество каждого элемента в списке O (n) раз.
Вычисление item ^ x
- это время O (1), а вычисление того, находится ли этот результат за dict
, - также время O (1). dict
ключ доступа также O (1), как и умножение двух элементов. Мы делаем все это n раз, следовательно, O (n) время для цикла.
O (n) + O (n) сокращается до времени O (n).
Отредактировано для правильной обработки дубликатов.