Программа курса:
Разбор задачи: K-я наименьшая простая дробь
Предложенный нами код:
def kthSmallestPrimeFraction(self, arr, k):
heap, used = [(arr[0] / arr[-1], 0, len(arr) - 1)], {(0, len(arr) - 1)}
for i in range(k):
try:
cur, l, r = heapq.heappop(heap)
used.add((l, r))
if (l + 1, r) not in used:
heapq.heappush(heap, (arr[l + 1] / arr[r], l + 1, r))
used.add((l + 1, r))
if (l, r - 1) not in used:
heapq.heappush(heap, (arr[l] / arr[r - 1], l, r - 1))
used.add((l, r - 1))
except:
break
return [arr[l], arr[r]]
Вот подробный разбор решения задачи, по шагам, без упоминания сложности:
1. Инициализация
heap, used = [(arr[0] / arr[-1], 0, len(arr) - 1)], {(0, len(arr) - 1)}
- Мы начинаем с того, что создаем кучу (
heap), в которой храним кортежи вида(значение, индекс левого элемента, индекс правого элемента). Первоначально в куче находится один кортеж: это отношение первого элемента массива (arr[0]) к последнему элементу массива (arr[-1]), и индексы этих элементов (0 и последний индекс массива). - Также создаем множество
used, чтобы отслеживать, какие индексы уже были обработаны и не попасть в цикл.
2. Основной цикл
for i in range(k):
try:
cur, l, r = heapq.heappop(heap)
used.add((l, r))
- Основной цикл выполняется
kраз. В каждой итерации мы извлекаем наименьшее отношение из кучи. Методheapq.heappop(heap)извлекает минимальный элемент из кучи и возвращает его как кортеж из трех элементов: значение отношения, индекс левого числа и индекс правого числа. - После этого добавляем пару индексов
(l, r)в множествоused, чтобы знать, что эта пара уже была рассмотрена.
3. Добавление новых элементов в кучу
if (l + 1, r) not in used:
heapq.heappush(heap, (arr[l + 1] / arr[r], l + 1, r))
used.add((l + 1, r))
if (l, r - 1) not in used:
heapq.heappush(heap, (arr[l] / arr[r - 1], l, r - 1))
used.add((l, r - 1))
- Если пара
(l+1, r)(сдвиг по левому индексу на 1) не была обработана, то мы добавляем ее в кучу. Это будет означать, что мы сдвигаем левую часть отношения вправо. - Точно так же, если пара
(l, r-1)(сдвиг по правому индексу на 1) не была обработана, мы добавляем эту пару в кучу, сдвигая правую часть отношения влево. - Важно заметить, что добавляем новые индексы только в том случае, если они еще не были обработаны, благодаря проверке с множеством
used.
4. Возврат результата
return [arr[l], arr[r]]
- После выполнения
kитераций, мы возвращаем пару чисел, которая соответствует индексу(l, r), на которых завершилось извлечение из кучи. Это будет пара чисел, образующихk-е наименьшее отношение в исходном массивеarr.
Пример
Вход: arr = [1, 2, 3, 5], k = 3
- На первом шаге кучу будут содержать отношения:
1/5,1/3,2/5, а минимальное отношение — это1/5. - После извлечения минимального отношения добавляется
1/3и1/2. - После извлечения еще одного отношения, добавляется
2/5, и на выходе получаем третий минимальный элемент2/5.
Выход: [2, 5]
Таким образом, мы эффективно находим k-е минимальное отношение, правильно управляя кучей и отслеживая уже обработанные индексы.
Вы должны Войти или Зарегистрироваться чтобы оставлять комментарии