Тривиальный подход состоит в том, чтобы вести список наборов и выполнять линейный поиск по нему для каждого входящего набора (проверка, является ли входящее подмножеством).
Это очевидно выполняется за O (n) время для линейного поиска и, возможно, O (m) размер для размера входящего набора. Таким образом, O (n * m) общее время (количество наборов против размера каждого набора).
Самой очевидной оптимизацией, конечно же, является индексирование по заданным размерам. Затем вы проверяете каждый входящий набор только на те, которые имеют одинаковый или больший размер. (Набор не может быть подмножеством любого меньшего набора, да!).
Следующая оптимизация, которая приходит на ум, - создание индекса элементов. Таким образом, для каждого входящего набора вы найдете пересечение каждого набора, содержащего каждый из элементов. Другими словами, если для входящего набора {a, b, c} мы находим, что элемент {a} существует в наборах A, B и D, элемент {b} существует в B, E и F, и {c} существует в A, B и Z ... тогда входящий набор является подмножеством B (пересечение {A, B, D}, {B, E, F} и {A, B, Z}).
Итак, для меня это звучит как O (m * log (n)) сложность. (Мы должны выполнить хэшированные поиски для каждого элемента каждого входящего набора). Вставки также должны быть в том же порядке (вставка идентификатора нового набора в каждую из карт элемента). (В анализе Big-O 2 * O (m log (n)), конечно, уменьшается до O (m log (n)).