Разбор задачи: Пары, держащиеся за руки

Предложенный нами код:

 def minSwapsCouples(row):
        res, index = 0, {num: i for i, num in enumerate(row)}
        for i in range(0, len(row), 2):
            if row[i] % 2 == 0 and row[i + 1] != row[i] + 1: 
                f = row[i + 1]
                row[i + 1], row[index[row[i] + 1]] = row[i] + 1, row[i + 1]
                index[row[i] + 1], index[f] = i + 1, index[row[i] + 1]
                res += 1
            elif row[i] % 2 != 0 and row[i + 1] != row[i] - 1:
                f = row[i + 1]
                row[i + 1], row[index[row[i] - 1]], index[row[i + 1]] = row[i] - 1, row[i + 1], index[row[i] - 1]
                index[row[i] - 1], index[f] = i + 1, index[row[i] - 1]
                res += 1
        return res

1. Инициализация переменных

res, index = 0, {num: i for i, num in enumerate(row)}
  • res — переменная для хранения количества сделанных перестановок.
  • index — словарь, который сопоставляет каждое число из массива row с его текущим индексом. Это позволяет быстро находить позицию любого человека в ряду.

Пример:
Если row = [0, 2, 1, 3], то index = {0: 0, 2: 1, 1: 2, 3: 3}.


2. Цикл по парам людей

for i in range(0, len(row), 2):
  • Цикл проходит по массиву row с шагом 2, так как пары находятся на соседних позициях: i и i + 1.

3. Обработка случая, когда ID первого человека чётный

if row[i] % 2 == 0 and row[i + 1] != row[i] + 1:
  • Если ID текущего человека row[i] чётный, его пара должна быть row[i] + 1.
  • Если человек на позиции row[i + 1] не является его парой, нужно выполнить перестановку.

Пример:
row = [0, 2, 1, 3],
на первой итерации row[i] = 0. Пара для 0 — это 1, но row[i + 1] = 2, что неправильно. Нужно поменять местами row[i + 1] и реальную пару 1.


4. Выполнение перестановки для чётного ID

f = row[i + 1]
row[i + 1], row[index[row[i] + 1]] = row[i] + 1, row[i + 1]
index[row[i] + 1], index[f] = i + 1, index[row[i] + 1]
res += 1
  • f — это ID человека, который сейчас занимает место рядом с row[i].
  • Выполняются следующие действия:
    1. На место row[i + 1] ставится его правильная пара row[i] + 1.
    2. На место, где ранее находилась правильная пара, ставится человек f.
    3. Обновляются индексы в словаре index, чтобы отражать изменения.
    4. Увеличивается счётчик перестановок res.

5. Обработка случая, когда ID первого человека нечётный

elif row[i] % 2 != 0 and row[i + 1] != row[i] - 1:
  • Если ID текущего человека row[i] нечётный, его пара должна быть row[i] - 1.
  • Если человек на позиции row[i + 1] не является его парой, нужно выполнить аналогичную перестановку.

6. Выполнение перестановки для нечётного ID

f = row[i + 1]
row[i + 1], row[index[row[i] - 1]], index[row[i + 1]] = row[i] - 1, row[i + 1], index[row[i] - 1]
index[row[i] - 1], index[f] = i + 1, index[row[i] - 1]
res += 1

Этот блок кода работает аналогично предыдущему, но с учётом того, что пара для нечётного ID — это row[i] - 1.


7. Возврат результата

return res

В конце возвращается количество выполненных перестановок.


Пример работы алгоритма

Рассмотрим входные данные row = [0, 2, 1, 3].

  1. Инициализация:
    • index = {0: 0, 2: 1, 1: 2, 3: 3}
    • res = 0
  2. Первая итерация (i = 0):

    • row[i] = 0 (чётный).
    • Ожидаемая пара: 1.
      Но row[i + 1] = 2, поэтому выполняется перестановка:
      • f = row[i + 1] = 2
      • Меняем местами row[i + 1] и row[index[1]]:
        row[1], row[2] = 1, 2
      • Обновляем index:
        index = {0: 0, 2: 2, 1: 1, 3: 3}
      • res = 1

    После первой итерации:
    row = [0, 1, 2, 3].

  3. Вторая итерация (i = 2):
    • row[i] = 2 (чётный).
    • Ожидаемая пара: 3.
      row[i + 1] = 3, пара правильная. Никаких действий не требуется.
  4. Результат:
    • Алгоритм завершён, res = 1.

 



Вы должны Войти или Зарегистрироваться чтобы оставлять комментарии