Реверс массива (разворот на месте)
1. Задача: развернуть массив
Условие
Изменить порядок элементов массива на обратный без создания нового массива.
Пример
До: [1, 2, 3, 4, 5]
После: [5, 4, 3, 2, 1]
2. Алгоритм
Идея: Менять местами элементы с противоположных концов, двигаясь к центру.
Шаги:
- Пройти до половины массива
- На каждой итерации поменять
array[i]сarray[opposite] opposite = len(array) - 1 - i— индекс с конца
3. Реализация
toReverse := [5]int{1, 2, 3, 4, 5}
for i := 0; i < len(toReverse)/2; i++ {
opposite := len(toReverse) - 1 - i
toReverse[i], toReverse[opposite] = toReverse[opposite], toReverse[i]
}
fmt.Printf("Результат: %v\n", toReverse)
Вывод:
Результат: [5 4 3 2 1]
4. Формула индекса opposite
opposite = len(array) - 1 - i
Примеры для массива из 5 элементов
len = 5
i=0: opposite = 5 - 1 - 0 = 4 // Первый ↔ Последний
i=1: opposite = 5 - 1 - 1 = 3 // Второй ↔ Предпоследний
i=2: opposite = 5 - 1 - 2 = 2 // Средний ↔ Сам с собой (не выполнится)
Почему -1? Индексация с 0 → последний индекс = len - 1.
5. Почему цикл до половины?
for i := 0; i < len(toReverse)/2; i++
Для массива из 5 элементов
len(toReverse) / 2 = 5 / 2 = 2 // Целочисленное деление
Итерации: i = 0, 1 (всего 2)
Что произойдёт, если i < len(array)?
i=0: меняем [0] ↔ [4] ✓
i=1: меняем [1] ↔ [3] ✓
i=2: меняем [2] ↔ [2] (бесполезно)
i=3: меняем [3] ↔ [1] ✗ Обратная замена!
i=4: меняем [4] ↔ [0] ✗ Снова обратная замена!
Результат: Массив вернётся к исходному виду.
6. Пошаговая трассировка
Исходный массив
Индекс: 0 1 2 3 4
Массив: [1, 2, 3, 4, 5]
Итерация 0 (i=0)
opposite = 5 - 1 - 0 = 4
Меняем: array[0] ↔ array[4]
1 ↔ 5
Результат: [5, 2, 3, 4, 1]
Итерация 1 (i=1)
opposite = 5 - 1 - 1 = 3
Меняем: array[1] ↔ array[3]
2 ↔ 4
Результат: [5, 4, 3, 2, 1]
Условие цикла
i=2: 2 < 5/2? → 2 < 2? → НЕТ
Цикл завершён
Итог: [5, 4, 3, 2, 1] ✅
7. Swap (обмен значений) в Go
Одновременное присваивание
a, b = b, a // Go автоматически создаёт временную переменную
В контексте массива
array[i], array[opposite] = array[opposite], array[i]
Эквивалент на других языках:
temp := array[i]
array[i] = array[opposite]
array[opposite] = temp
8. Реверс для чётного количества элементов
Массив из 6 элементов
Индекс: 0 1 2 3 4 5
Массив: [1, 2, 3, 4, 5, 6]
len / 2 = 6 / 2 = 3
Итерации:
i=0: [0] ↔ [5] → [6, 2, 3, 4, 5, 1]
i=1: [1] ↔ [4] → [6, 5, 3, 4, 2, 1]
i=2: [2] ↔ [3] → [6, 5, 4, 3, 2, 1]
Результат: [6, 5, 4, 3, 2, 1] ✅
9. Отладка через debugger
Точка останова
for i := 0; i < len(toReverse)/2; i++ {
opposite := len(toReverse) - 1 - i
// ← breakpoint
toReverse[i], toReverse[opposite] = toReverse[opposite], toReverse[i]
}
Что отслеживать
i— текущий индекс с началаopposite— индекс с концаtoReverse[i]— значение слеваtoReverse[opposite]— значение справа- Массив после обмена
10. Варианты задачи
Реверс подмассива (с индекса start до end)
func reverseRange(arr []int, start, end int) {
for start < end {
arr[start], arr[end] = arr[end], arr[start]
start++
end--
}
}
Проверка на палиндром
func isPalindrome(arr [5]int) bool {
for i := 0; i < len(arr)/2; i++ {
if arr[i] != arr[len(arr)-1-i] {
return false
}
}
return true
}
11. Типичные ошибки
❌ Цикл до конца массива:
for i := 0; i < len(array); i++ // Массив вернётся в исходное состояние
❌ Неправильная формула opposite:
opposite := len(array) - i // Выход за границы!
❌ Забыли swap:
toReverse[i] = toReverse[opposite] // Потеря данных!
✅ Правильно:
toReverse[i], toReverse[opposite] = toReverse[opposite], toReverse[i]
12. Итоги
✅ Реверс = обмен элементов с противоположных концов
✅ Цикл до половины: i < len/2
✅ Формула: opposite = len - 1 - i
✅ Swap в Go: a, b = b, a
✅ Работает для массивов чётной и нечётной длины
Паттерн:
for i := 0; i < len(array)/2; i++ {
opposite := len(array) - 1 - i
array[i], array[opposite] = array[opposite], array[i]
}
Практика: Разверните массив строк, реализуйте реверс без временной переменной, проверьте массив на симметричность.