ОБНОВЛЕНИЕ : без итерации какого-либо набора, используются только операции набора
Этот алгоритм строит наборы результатов конструктивно, то есть мы модифицируем существующие уникальные наборы элементов и / или добавляем новые каждый размы видим новый исходный набор.
Идея состоит в том, что каждый новый набор можно разбить на две части, одну с уже увиденными значениями, а другую с новыми уникальными значениями.Для первой части он далее делится на различные подмножества (до # набора мощности видимых исходных наборов) текущими наборами результатов.Для каждого такого подмножества оно также разбивается на две части: одна пересекается с новым исходным набором, а другая - нет.Задача состоит в том, чтобы обновить наборы результатов для каждой из этих категорий.
Для сложности с точки зрения операций над множествами это должно быть O (n * 2 ^ n).Для решения, опубликованного ОП, я думаю, что сложность должна быть O (2 ^ (2n)), потому что len(resulting_sets)
имеет до 2 ^ n элементов в худшем случае.
def solution(sets):
result_sets = [] # list of (unique element set, membership) tuples
for sid, s in enumerate(sets):
new_sets = []
for unique_elements, membership in result_sets:
# The intersect part has wider membership, while the other part
# has less unique elements (maybe empty).
# Wider membership must have not been seen before, so add as new.
intersect = unique_elements & s
# Special case if all unique elements exist in s, then update
# in place
if len(intersect) == len(unique_elements):
membership.append(sid)
elif len(intersect) != 0:
unique_elements -= intersect
new_sets.append((intersect, membership + [sid]))
s -= intersect
if len(s) == 0:
break
# Special syntax for Python: there are remaining elements in s
# This is the part of unseen elements: add as a new result set
else:
new_sets.append((s, [sid]))
result_sets.extend(new_sets)
print(result_sets)
sets = [{1, 2, 3}, {1, 4, 7}, {1, 4, 5}]
solution(sets)
# output:
# [(set([2, 3]), [0]), (set([1]), [0, 1, 2]), (set([7]), [1]), (set([4]), [1, 2]), (set([5]), [2])]
-------------- оригинальный ответ ниже ---------------
Идея состоит в том, чтобы найти «членство» каждого уникального элементат.е. к каким наборам он принадлежит.Затем мы создаем словарь для группировки всех элементов по их принадлежности, генерируя запрошенные множества.Сложность O (n * len (множеств)) или O (n ^ 2) в худшем случае.
def solution(sets):
union = set().union(*sets)
numSets = len(sets)
numElements = len(union)
memberships = {}
for e in union:
membership = tuple(i for i, s in enumerate(sets) if e in s)
if membership not in memberships:
memberships[membership] = []
memberships[membership].append(e)
print(memberships)
sets = [{1, 2, 3}, {1, 4, 7}, {1, 4, 5}]
solution(sets)
# output:
# {(0, 1, 2): [1], (1, 2): [4], (0,): [2, 3], (1,): [7], (2,): [5]}