def MinimumSwaps(Queue):
MinSwaps = 0
for i in range(len(Queue) - 1):
if Queue[i] != i+1:
for j in range(i+1,len(Queue)):
if Queue[j] == i+1:
Queue[i], Queue[j] = Queue[j], Queue[i]
MinSwaps += 1
break
else:
continue
return MinSwaps
def main():
Result = MinimumSwaps([7, 1, 3, 2, 4, 5, 6])
print(Result)
if __name__ == "__main__":
main()
Вопрос: Вам дан неупорядоченный массив, состоящий из последовательных целых чисел [1, 2, 3, …, n] без дубликатов. Вы можете поменять местами любые два элемента. Вам нужно найти минимальное количество свопов, необходимых для сортировки массива в порядке возрастания.
Проблема в том, что то, что я предоставил, неэффективно и не работает на очень больших массивах, однако я попытался оптимизировать его настолько, насколько мог, и я не знаю другого метода, который можно использовать. Этот вопрос, вероятно, связан с конкретным алгоритмом сортировки, но есть ли способ изменить приведенный выше код, чтобы сделать его быстрее?
2 ответа
Вместо поиск для значения, которое принадлежит Queue[i] чтобы поменять его там, просто поменяйте местами значение, которое является там, где это принадлежит:
def MinimumSwaps(Queue):
MinSwaps = 0
for i in range(len(Queue) - 1):
while Queue[i] != i + 1:
j = Queue[i] - 1
Queue[i], Queue[j] = Queue[j], Queue[i]
MinSwaps += 1
return MinSwaps
Это улучшает производительность до $ O (1) $ для использования значения вместо $ O (п) $ для поиска. И таким образом общая производительность $ O (п) $ вместо вашего оригинала $ O (п ^ 2) $. По-прежнему используется только O (1) дополнительного места.
Ваш код $ O (п ^ 2) $ из-за внутреннего цикла.
for j in range(i+1,len(Queue)): if Queue[j] == i+1: # inner
Мы можем изменить это на $ O (1) $ сделав таблицу поиска, где $ i $местонахождение. Мы можем создать словарь для хранения этих запросов.
indexes = {value: index for index, value in enumerate(Queue)
Затем мы можем просто поменять эти индексы на ваш существующий внутренний код, чтобы получить $ O (п) $ спектакль.
def MinimumSwaps(Queue):
indexes = {value: index for index, value in enumerate(Queue)}
MinSwaps = 0
for i in range(len(Queue) - 1):
i_value = Queue[i]
if i_value != i+1:
j = indexes[i+1]
j_value = Queue[j]
Queue[i], Queue[j] = Queue[j], Queue[i]
indexes[i_value], indexes[j_value] = indexes[j_value], indexes[i_value]
MinSwaps += 1
else:
continue
return MinSwaps
Возможная производительность таблицы достигается за счет использования словаря в качестве таблицы поиска, а не списка. Хотя оба имеют одинаковую алгоритмическую сложность. Чтобы решить эту проблему, мы можем просто построить indexes в виде списка.
indexes = [None] * len(Queue)
for index, value in enumerate(Queue):
indexes[value] = index
Почему за этот ответ не проголосовали? Возможно, это не лучшая идея. Но это, по крайней мере, работает (повысьте производительность за счет уменьшения большой временной сложности исходного кода).
— тш
@tsh Другой пользователь испытывал ко мне нездоровую неприязнь. Так что проголосовали против сразу после того, как увидели, кто опубликовал ответ. Второй, ИДК. Как вы говорите, ответ ответил на вопрос, улучшив производительность кода, может ли мой ответ быть плохо сформулирован или что-то в этом роде? Я НЕ ЗНАЮ. Спекуляция, вероятно, не лучшая идея, если я не получу еще пару голосов против. Так что пока я просто предполагаю Тим снова потерял ключи.
— Пейлонрайз
@tsh Я считаю, что путь ОП идет в неправильном направлении (решение к текущее место в списке вместо более простого и быстрого прочь из текущего места в списке) и, следовательно, это решение как Бег в неправильном направлении, с даже более сложный код и меньшая экономия места. К тому же совсем недавно они подняли шум по поводу того, что операции set являются O (n) вместо O (1), что они должны были сделать здесь и для dict.
— отличный дождь
@superbrain «что они тогда должны были сделать здесь» Я сделал, посмотрите внизу сообщения.
— Пейлонрайз
Где? Вы даже прямо говорите: «Мы можем изменить это значение на O (1)».
— отличный дождь

Мне понадобится его пример, реализованный в моем коде.
— Джек
Не могли бы те, кто проголосовал против, объяснить, что с ними не так?
— отличный дождь
@FMc Подозреваю, что это снова пейлонрайз, продолжает голосовать против моих материалов по серьезным причинам, и всякий раз, когда я получаю странное отрицательное голосование, они только что были в сети.
— отличный дождь
@superbrain Вы явно не объяснили, как это улучшает производительность. И ваше предложение будет усреднено, чтобы ничего не делать на случайных входах.
— Пейлонрайз
@superbrain Я не думал, что можно так изменить код. Потому что ваш ответ был очень плохим по поводу объяснения.
— Пейлонрайз
Показать 3 больше комментариев