Это стандартная проблема в алгоритмах потоковой передачи (где у вас огромный (потенциально бесконечный) поток данных), и вам необходимо вычислить некоторую статистику из этого потока, проходящего через этот поток один раз.
Очевидно, что вы можете обратиться к нему с помощью хэширования или сортировки, но с потенциально бесконечным потоком у вас явно не хватит памяти. Так что вы должны сделать что-то умное здесь.
Мажоритарный элемент - это элемент, размер которого превышает половину размера массива . Это означает, что мажоритарный элемент встречается чаще, чем все остальные элементы вместе взятые, или если вы посчитаете количество раз, появится мажоритарный элемент и вычтете количество всех остальных элементов, вы получите положительное число.
Так что, если вы посчитаете номер какого-либо элемента, вычтете число всех других элементов и получите число 0 - тогда ваш исходный элемент не может быть элементом большинства. Это если основа для правильного алгоритма:
Есть две переменные, счетчик и возможный элемент. Итерируйте поток, если счетчик равен 0 - перезаписать возможный элемент и инициализировать счетчик, если число совпадает с возможным элементом - увеличить счетчик, иначе уменьшить его. Код Python:
def majority_element(arr):
counter, possible_element = 0, None
for i in arr:
if counter == 0:
possible_element, counter = i, 1
elif i == possible_element:
counter += 1
else:
counter -= 1
return possible_element
Ясно, что алгоритм O(n)
с очень маленькой константой до O(n)
(например, 3). Также похоже, что сложность пространства равна O(1)
, потому что у нас только три инициализированные переменные. Проблема в том, что одна из этих переменных является счетчиком, который потенциально может вырасти до n
(когда массив состоит из одинаковых чисел). А для хранения числа n
нужно O(log (n))
пробела. Так что с теоретической точки зрения это O(n)
время и O(log(n))
пространство. Из практического вы можете поместить 2 ^ 128 в длинную строку, и это количество элементов в массиве невообразимо огромно.
Также обратите внимание, что алгоритм работает только при наличии элемента контрольного пакета. Если такого элемента не существует, он все равно вернет некоторое число, что, несомненно, будет неправильным. (алгоритм легко модифицировать, чтобы определить, существует ли мажоритарный элемент)
Канал истории: этот алгоритм был изобретен где-то в 1982 году Бойером, Муром и назван Алгоритмом большинства голосов Бойера-Мура .