Печально видеть, что за 5 лет никто не написал надлежащего объяснения этой проблемы.
Это стандартная проблема в алгоритмах потоковой передачи (где у вас огромный (потенциально бесконечный) поток данных) и вам нужно вычислить некоторую статистику из этого потока, проходящего через этот поток один раз.
Очевидно, что вы можете обратиться к нему с помощью хеширования или сортировки, но с потенциально бесконечным потоком вы можете явно исчерпать память,Таким образом, вы должны сделать что-то умное здесь.
Мажоритарный элемент - это элемент, размер которого превышает половину размера массива .Это означает, что мажоритарный элемент встречается чаще, чем все остальные элементы вместе взятые.То есть, если вы посчитаете, сколько раз появляется элемент контрольного числа, и вычтете количество вхождений всех других элементов, вы получите положительное число.
Так что, если вы посчитаете вхождения некоторого элемента,и вычтите количество вхождений всех других элементов и получите число 0 - тогда ваш исходный элемент не может быть элементом большинства.Это основа для правильного алгоритма:
Объявите две переменные, counter и возможных_элементов.Повторяйте поток, если счетчик равен 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 году Бойером, Муром и назван Алгоритмом большинства голосов Бойера-Мура