Программа курса:
Разбор задачи: Пересечения списка интервалов
Предложенный нами код:
def intervalIntersection(firstList, secondList):
"""
:param firstList: List[List[int]] - первый список интервалов
:param secondList: List[List[int]] - второй список интервалов
:return: List[List[int]] - список пересечений интервалов
"""
i, j = 0, 0
result = []
while i < len(firstList) and j < len(secondList):
# Находим начало и конец возможного пересечения
start = max(firstList[i][0], secondList[j][0])
end = min(firstList[i][1], secondList[j][1])
# Если начало <= конца, то есть пересечение
if start <= end:
result.append([start, end])
# Двигаемся дальше по списку, где интервал закончился раньше
if firstList[i][1] < secondList[j][1]:
i += 1
else:
j += 1
return resultФрагмент 1: Инициализация переменных
i, j = 0, 0
result = []
iиj— указатели, которые будут проходить поfirstListиsecondListсоответственно.result— список, в который мы будем добавлять пересечения интервалов.
Фрагмент 2: Основной цикл
while i < len(firstList) and j < len(secondList):
- Цикл продолжается, пока оба указателя находятся в пределах своих списков. Если один из списков заканчивается, дальнейшие пересечения невозможны.
Фрагмент 3: Вычисление пересечения
start = max(firstList[i][0], secondList[j][0])
end = min(firstList[i][1], secondList[j][1])
- Мы вычисляем возможное пересечение текущих интервалов:
start— максимальное из начальных значений текущих интервалов. Это гарантирует, что пересечение начнется с большего значения.end— минимальное из конечных значений текущих интервалов. Это гарантирует, что пересечение завершится раньше, чем любой из интервалов.
Фрагмент 4: Проверка и добавление пересечения
if start <= end:
result.append([start, end])
- Если начало пересечения
startменьше или равно концуend, это означает, что пересечение существует. Его добавляют в списокresult.
Фрагмент 5: Перемещение указателей
if firstList[i][1] < secondList[j][1]:
i += 1
else:
j += 1
- Мы перемещаем указатель на интервал, который заканчивается раньше:
- Если текущий интервал в
firstListзаканчивается раньше, двигаем указательi. - Иначе двигаем указатель
j.
- Если текущий интервал в
Фрагмент 6: Возврат результата
return result
- Возвращаем список всех пересечений.
Пошаговая работа алгоритма (пример)
Рассмотрим пример:
firstList = [[0, 2], [5, 10], [13, 23], [24, 25]]
secondList = [[1, 5], [8, 12], [15, 24], [25, 26]]
- Начальные значения:
i = 0,j = 0,result = [].
- Цикл 1:
- Текущие интервалы:
[0, 2]и[1, 5]. start = max(0, 1) = 1,end = min(2, 5) = 2.- Пересечение:
[1, 2]. Добавляем вresult. firstList[0][1] < secondList[0][1]→i += 1.
- Текущие интервалы:
- Цикл 2:
- Текущие интервалы:
[5, 10]и[1, 5]. start = max(5, 1) = 5,end = min(10, 5) = 5.- Пересечение:
[5, 5]. Добавляем вresult. firstList[1][1] > secondList[0][1]→j += 1.
- Текущие интервалы:
- Цикл 3:
- Текущие интервалы:
[5, 10]и[8, 12]. start = max(5, 8) = 8,end = min(10, 12) = 10.- Пересечение:
[8, 10]. Добавляем вresult. firstList[1][1] < secondList[1][1]→i += 1.
- Текущие интервалы:
- Цикл 4:
- Текущие интервалы:
[13, 23]и[8, 12]. - Нет пересечения. Двигаем
j.
- Текущие интервалы:
- Цикл 5:
- Текущие интервалы:
[13, 23]и[15, 24]. start = max(13, 15) = 15,end = min(23, 24) = 23.- Пересечение:
[15, 23]. Добавляем вresult. - Двигаем
i.
- Текущие интервалы:
- Цикл 6:
- Текущие интервалы:
[24, 25]и[15, 24]. start = max(24, 15) = 24,end = min(25, 24) = 24.- Пересечение:
[24, 24]. Добавляем вresult. - Двигаем
j.
- Текущие интервалы:
- Цикл 7:
- Текущие интервалы:
[24, 25]и[25, 26]. start = max(24, 25) = 25,end = min(25, 26) = 25.- Пересечение:
[25, 25]. Добавляем вresult. - Двигаем
i.
- Текущие интервалы:
- Цикл завершён:
i = 4,j = 4. Выходим из цикла.
Итоговый результат
Результат для приведённого примера:
result = [[1, 2], [5, 5], [8, 10], [15, 23], [24, 24], [25, 25]]
Этот результат возвращается функцией.
Вы должны Войти или Зарегистрироваться чтобы оставлять комментарии