В данном конкретном случае речь идет не столько об алгоритме, а о структуре данных: Multiset
- это как Set
, за исключением того, что он не хранит только уникальные элементы, вместо этого он хранит подсчет того, как часто каждый элемент в Multiset
. В основном, Set
говорит вам, является ли конкретный элемент в Set
на всех, в дополнение к этому Multiset
также сообщает вам как часто этот конкретный пункт в Multiset
.
Итак, в основном все, что вам нужно сделать, это построить Multiset
от вашего Array
. Вот пример в Ruby:
require 'multiset'
print Multiset[1,1,3,0,5,1,5]
Да, это все, что нужно. Эта печать:
#3 1
#1 3
#1 0
#2 5
Если вы хотите только фактические дубликаты, вы просто delete
эти пункты с числом менее 2
:
print Multiset[1,1,3,0,5,1,5].delete_with {|item, count| count < 2 }
Это печатает только
#1 3
#2 5
Как @suihock упоминает , вы также можете использовать Map
, что в основном означает, что вместо Multiset
, заботясь о подсчете элементов для вы, вы должны сделать это сами:
m = [1,1,3,0,5,1,5].reduce(Hash.new(0)) {|map, item| map.tap { map[item] += 1 }}
print m
# { 1 => 3, 3 => 1, 0 => 1, 5 => 2 }
Опять же, если вы хотите только дублированные:
print m.select {|item, count| count > 1 }
# { 1 => 3, 5 => 2 }
Но вы можете иметь, что проще, если вместо того чтобы считать себя, вы используете Enumerable#group_by
к группе по элементы сами по себе, а затем сопоставляют группировки с их размерами.И, наконец, преобразовать обратно в Hash
:
print Hash[[1,1,3,0,5,1,5].group_by(&->x{x}).map {|n, ns| [n, ns.size] }]
# { 1 => 3, 3 => 1, 0 => 1, 5 => 2 }
Все они имеют амортизируется наихудший шаг сложности Θ (п).
thanks Итак, ваш алгоритм будет O (n)? – user472221
Да, это всего лишь одна петля. – Emil
благодарит заранее – user472221