Это можно сделать за линейное время, используя два указателя (влево и вправо), пересекающих отсортированный список событий.Фактически, обход выполняется в отсортированном списке событий вызова, который содержит как события начала вызова, так и события окончания вызова.
Левый указатель начинается с самого левого события запуска.Правый указатель перемещается к последнему событию не позднее (время левого времени + 1 час).Мы также поддерживаем переменную sum , которая вычисляет сумму всех длительностей вызовов в интервале.
На каждой итерации мы перемещаем левый указатель к следующему событию (соответственно обновляя сумму), а затем продвигаемся по правому указателю (снова обновляя сумму) до его конечной позиции (чуть менее 1 часа).позже).
Максимальное значение сумма получено в окне занятого часа.
Я не дал подробностей о том, как обновить переменную суммы при перемещенииуказатели, но я считаю, что это не должно быть сложно сделать это в постоянное время.
Преимущество этого алгоритма состоит в том, что он не имеет проблемы гранулярности, и что он является линейным по количеству событий.
- РЕДАКТИРОВАТЬ -
На самом деле это алгоритм O (N * Log N), поскольку входная таблица не обеспечивает сортировку событий, которые я предполагал.Сначала нужно сгенерировать отсортированные списки событий