Как узнать
список пар [начало, конец], например встреч или бронирований, и вопрос о том, что пересекается.
Как решать такие задачи
- Отсортируй по началу. Чтобы оставить как можно больше непересекающихся интервалов, сортируй по концу.
- Реши, пересекаются ли интервалы, которые только касаются: начало ≤ последнего конца или начало < последнего конца.
- Пройди один раз и сравнивай каждый интервал только с последним сохранённым: продли его или начни новый.
- Чтобы узнать, сколько интервалов идёт одновременно, преврати каждый в +1 в начале и −1 в конце, отсортируй эти точки и веди текущую сумму.
Вариант: Сортировка по концу
То же, но сортируем по концу. Так выбирают как можно больше непересекающихся отрезков или как можно меньше точек, которые попадут во все: отрезок, который кончается раньше всех, оставляет больше места остальным.
- Сортируй по концу, когда жадно выбираешь точки или интервалы и первым должен идти тот, что кончается раньше.
- Помни только последний выбор: здесь последний выстрел, конец интервала, ради которого стреляли.
- Интервалу, который начинается правее него, нужен новый выбор в его собственном конце. Всё остальное уже покрыто — пропускай.
- Чтобы оставить как можно больше непересекающихся интервалов, сортируй так же по концу: бери интервал, если он начинается после конца последнего взятого, остальные выбрасывай.
Где встречается
- Видео в браузере. Браузер хранит, какие куски видео уже скачаны, как список отрезков времени. Пересекающиеся и соседние отрезки он сливает в один, поэтому список остаётся коротким и упорядоченным.
- Генетика. bedtools merge склеивает пересекающиеся участки генома. Файл сначала сортируют по началу, а потом каждый участок сравнивают только с предыдущим.
- PostgreSQL. PostgreSQL умеет хранить диапазоны дат и чисел. Функция range_agg собирает много диапазонов в набор без пересечений, сливая те, что перекрываются.