#java #algorithm
Вопрос:
У меня есть класс Period
, который представлен start
и end
датами, где end
после start
. Мне нужно написать функцию, чтобы проверить, перекрываются ли периоды.
Простой подход состоит в том, чтобы сверять каждый период с каждым другим периодом. Есть ли способ представить структуру данных, которая будет работать быстрее?
class Period {
LocalDateTime start;
LocalDateTime end;
}
boolean isOverlap(Set<Period> periods) {
// TODO put the code here
}
isOverlap
должен вернуться true
, когда по крайней мере два периода перекрываются.
Комментарии:
1. Не могли бы вы уточнить, когда
isOverlap
следует вернуть значение true? Должно ли это происходить, когда все периоды перекрывают все остальные периоды?2. Я бы реализовал
Comparable
интерфейс. Затем с aTreeSet
вы можете сравнить по порядку.3. @Гобой Точно, как бы вы реализовали
compareTo
пару свиданий или пару моментов? Является ли Хэллоуин к Рождеству больше или меньше, чем с 1 по 20 ноября?4. @Basil Bourque Это зависит от того, чего вы хотите достичь. Для этого конкретного случая я бы реализовал его так же, как
Stream
сортируется в принятом ответе.
Ответ №1:
Проверка каждого периода по сравнению с каждым другим периодом будет иметь временную сложность O(n 2). Вместо этого я бы отсортировал их по времени начала и окончания, а затем повторил бы список. Таким образом, период может перекрывать только периоды непосредственно до и после него (или несколько последующих периодов до или после него — но это несущественно, так как вы ищете единственное перекрытие для возврата true
). Вы можете просмотреть список и проверить это. Общая стоимость этого алгоритма будет равна стоимости сортировки, O(nlog(n)):
boolean isOverlap(Set<Period> periods) {
List<Period> sorted =
periods.stream()
.sorted(Comparator.comparing((Period p) -> p.start)
.thenComparing(p -> p.end))
.collect(Collectors.toList());
for (int i = 0; i < sorted.size() - 1; i) {
if (sorted.get(i).end.compareTo(sorted.get(i 1).start) > 0) {
return true;
}
}
return false;
}
Комментарии:
1. Я думаю, что это должно быть » > 0`, чтобы это сработало.
2. @yu.pitomets arg, да, это верно. Там был кратковременный провал в концентрации, извините за это. Спасибо, что заметили! Отредактировано и исправлено.