Задать вопрос

Задача со множествами, помогите решить

Есть набор множеств

set(1, 2)
set(3)
set(4, 5)
set(3, 2, 6)
set(6)
set(7, 8)
set(9, 8)


Нужно объединить все множества которые пересекаются.

Так например set(1, 2) нужно объединить с set(3, 2, 6) и с set(3). Аналогично нужно проделать со всеми множествами.

Результат должен получиться такой:

set(1, 2, 3, 6)
set(4,5)
set(7, 8, 9)


Дополнительные условия.
Количество множеств — 5 миллионов.
Множества выбраны таким образом, что одно множество в среднем объединяется с 1-5 другими множествами. Будем считать, что количество множеств с которым может быть объединено любое множество из этого набора никогда не превышает 10.

Я могу придумать какие-то алгоритмы, но у них всех сложность n^2. И это выполняется очень долго. Хотелось бы получить линейный алгоритм.
  • Вопрос задан
  • 4078 просмотров
Подписаться 5 Оценить 4 комментария
Решение пользователя B@rmaley.e><e К ответам на вопрос (4)
barmaley_exe
@barmaley_exe
Обозначим: n — количество множеств, m — суммарное количество элементов во множествах, k — количество уникальных элементов в объединении всех множеств.

Решение за O(m):
Создать k множеств из одного элемента. Далее проходим по исходным множествам, считая каждое множество запросом на объединение. А именно, проходим по элементам множества и объединяем множество, соответствующее текущему элементу со множеством, соответствующим предыдущему. Чтобы делать это быстро пригодится структура система непересекающихся множеств. Эта структура позволяет выполнять нужные операции в среднем столь быстро, что можно считать их O(1) (хотя, строго говоря, асимптотика там не константная, см. статью).
В результате такого прохода мы обработаем каждый из m элементов один раз, затратив на него ≈O(1) времени. Отсюда получается оценка O(m).
В худшем случае такой алгоритм будет работать за O(n*k) (в каждом множестве можно избавиться от повторов, поэтому элементов в нём будет не более k).

Мне кажется, предложенный алгоритм является оптимальным: в любом случае нужно рассмотреть каждый элемент каждого множества, что даёт оценку в минимум O(m) операций.
Ответ написан