1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 |--------------------------------------X---------|
2 |--------------------------------X--------------------------------------------|
3 |--------------------------X---|
4 |-X-------------------------------------|
5 |--------X------------------------------|
6 |--------------------X----------|
7 |---------------------------|
+1 +1 +1 +1 +1 +1 -1 -2 +1 -1 -1 -2
1 2 3 4 5 6 5 3 4 3 2 0
^^^^
Получите это?
Так что вам нужно преобразовать это:
1: 2 - 10
2: 3 - 15
3: 4 - 9
4: 8 - 14
5: 7 - 13
6: 5 - 10
7: 11 - 15
в:
[(2,+), (3,+), (4,+), (5,+), (7,+), (8,+), (9,-), (10,-), (10,-), (11,+), (13,-), (14,-), (15,-), (15,-)]
и затем вы просто перебираете счетвверх, когда вы видите + и рассчитывает на -.Самый загруженный интервал будет, когда счетчик максимален.
Так в коде:
intervals = [(2, 10), (3, 15), (4, 9), (8, 14), (7, 13), (5, 10), (11, 15)]
intqueue = sorted([(x[0], +1) for x in intervals] + [(x[1], -1) for x in intervals])
rsum = [(0,0)]
for x in intqueue:
rsum.append((x[0], rsum[-1][1] + x[1]))
busiest_start = max(rsum, key=lambda x: x[1])
# busiest_end = the next element in rsum after busiest_start
# instead of using lambda, alternatively you can do:
# def second_element(x):
# return x[1]
# busiest_start = max(rsum, key=second_element)
# or:
# import operator
# busiest_start = max(rsum, key=operator.itemgetter(1))
сложность времени выполнения (n+n)*log(n+n)+n+n
или O(n*log(n))
Это также возможнопреобразовать эту идею в онлайн-алгоритм , если у вас нет полного списка интервалов в начале программы, но гарантировано, что входящие интервалы никогда не будут запланированы для прошедшей точки.Вместо сортировки вы будете использовать приоритетную очередь, каждый раз, когда наступает интервал, вы добавляете два элемента: начальную и конечную точки, каждая из которых имеет +1 и -1 соответственно.А потом вы выскакиваете, считаете и отслеживаете час пик.