Расширяя решение Амита, вместо сохранения фактических чисел вы можете просто хранить интервалы и связанные с ними наборы.
Например, используя размер интервала 5:
(1-5): [1,2,3,1000000]
(6-10): [2,1000000]
(11-15): [3]
(16-20): [1000000]
В случае (1,7) следует рассматривать интервалы (1-5) и (5-10) (которые можно определить, просто зная размер интервала). Пересечение этих диапазонов дает вам [2,1000000]. Бинарный поиск наборов показывает, что (1,7) действительно существует в обоих наборах.
Хотя вы захотите проверить минимальное и максимальное значения для каждого набора, чтобы лучше понять, каким должен быть размер интервала. Например, 5, вероятно, плохой выбор, если минимальное и максимальное значения варьируются от 1 до миллиона.
Вероятно, вам следует сохранить его, чтобы можно было использовать двоичный поиск для проверки значений, поэтому диапазон подмножества должен быть примерно таким (min + max)/N, где 2N — это максимальное количество значений, которые необходимо будет найти в двоичном формате. каждый набор. Например, «содержит ли набор 3 какие-либо значения от 5 до 10?» это делается путем нахождения ближайших значений к 5 (3) и 10 (11), в данном случае нет это не так. Вам нужно будет просмотреть каждый набор и выполнить двоичный поиск значений интервала, которые могут быть в наборе. Это означает, что вы не будете искать 100, когда набор достигает только 10.
Вы также можете просто сохранить диапазон (минимум и максимум). Однако проблема в том, что я подозреваю, что ваши номера будут сгруппированы, что не принесет большой пользы. Хотя, как уже упоминалось, это, вероятно, будет полезно для определения того, как настроить интервалы.
По-прежнему будет сложно выбрать, какой диапазон использовать, слишком велик, и потребуется много времени для построения структуры данных (1000 * миллионов * log (N)). Слишком маленький, и вы начнете сталкиваться с проблемами свободного места. Идеальный размер диапазона, вероятно, таков, что он гарантирует, что количество наборов, связанных с каждым диапазоном, приблизительно равно, а также гарантирует, что общее количество диапазонов не слишком велико.
Изменить: одно из преимуществ заключается в том, что вам не нужно хранить все интервалы, а только те, которые вам нужны. Хотя, если у вас слишком много неиспользуемых интервалов, может быть целесообразно увеличить интервал и разделить текущие интервалы, чтобы обеспечить быстрый поиск. Это особенно верно, если время процессии не является серьезной проблемой.
person
Nuclearman
schedule
02.01.2013
Set
уже есть.containsAll()
, я полагаю, вы пробовали это? Или вы действительно хотите избежать встроенных решений? Кроме того, ваши наборы всегда сортируются? - person fge   schedule 02.01.2013