Как реализовать реверс массива без использования компиляции
Что проверяют
Формулировка странная, и первое, что проверяют, это умение уточнить задачу. Обычно имеют в виду одно из двух: написать код без запуска, «в блокноте», или развернуть массив без встроенных средств вроде [::-1] и reversed(). Следом почти всегда просят сделать это на месте, без дополнительной памяти.
Как отвечать
Спросите вслух, что именно запрещено и можно ли менять исходный массив. Затем дайте решение двумя указателями:
- алгоритм:
i = 0,j = len(a) - 1, покаi < j, меняетеa[i], a[j] = a[j], a[i]и сдвигаете указатели навстречу; - сложность: O(n) по времени, O(1) по памяти, обменов ровно
n // 2; - вариант с копией: новый список, заполненный с конца, тоже O(n), но занимает вторую порцию памяти. Годится, если исходник менять нельзя.
Если код пишется без запуска, проверьте его руками, проговаривая трассировку: пустой массив, один элемент, чётная и нечётная длина. Интервьюер именно этого и ждёт.
Для data-ml добавьте контекст NumPy, это покажет, что вы думаете о реальных данных:
arr[::-1]: срез с отрицательным шагом возвращает представление (view) без копирования, за O(1);np.flip(arr, axis=0): тоже представление, удобно для многомерных массивов и выбора оси;- цикл в Python: поэлементный обмен на миллионах значений на порядки медленнее векторных операций, поэтому для
ndarrayего не пишут.
Где спотыкаются
Гонят цикл обмена по всей длине, а не до середины. Каждая пара меняется дважды, и массив возвращается в исходный вид. Без запуска такую ошибку видно только при ручной трассировке.
Путают API: list.reverse() разворачивает на месте и возвращает None, а reversed() отдаёт итератор, а не список. Строка a = a.reverse() оставляет вас с None.
Забывают, что срез NumPy это представление: изменили b = arr[::-1], изменился и arr. Нужна независимая копия, пишите arr[::-1].copy().