Как перевернуть (развернуть) массив в Java - Вопросы
Всего: 5 вопросов
1. Как перевернуть массив в Java на месте, не выделяя дополнительную память?
Как перевернуть массив в Java на месте, не выделяя дополнительную память?
Нужно поменять местами симметричные элементы: перебираем индексы от начала до середины (i < array.length / 2) и меняем местами array[i] и array[array.length - i - 1] через временную переменную. Цикл проходит только половину массива; при нечётной длине центральный элемент остаётся на месте. Алгоритм работает за O(n) по времени и O(1) по памяти.
public static void invert(int[] array) {
for (int i = 0; i < array.length / 2; i++) {
int tmp = array[i];
array[i] = array[array.length - i - 1];
array[array.length - i - 1] = tmp;
}
}
2. Почему метод реверса корректно работает на пустом массиве и массиве из одного элемента, и на каких случаях его стоит проверять?
Почему метод реверса корректно работает на пустом массиве и массиве из одного элемента, и на каких случаях его стоит проверять?
Проверять метод стоит на граничных случаях: пустой массив, один элемент, чётная и нечётная длина. Для пустого массива и массива из одного элемента array.length / 2 равно нулю, поэтому цикл не выполняется ни разу и массив остаётся без изменений — исключения не возникает. Для вывода удобно использовать Arrays.toString():
[] => []
[0] => [0]
[0, 1] => [1, 0]
[0, 1, 2] => [2, 1, 0]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] => [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
3. Как развернуть массив, не изменяя оригинал?
Как развернуть массив, не изменяя оригинал?
Реверс на месте меняет исходный массив. Чтобы сохранить оригинал, создаём новый массив той же длины и заполняем его, идя по исходному массиву с конца: result[i] = source[source.length - 1 - i]. Такой подход требует O(n) дополнительной памяти, зато не портит входные данные.
public static int[] reversedCopy(int[] source) {
int[] result = new int[source.length];
for (int i = 0; i < source.length; i++) {
result[i] = source[source.length - 1 - i];
}
return result;
}
4. Как перевернуть массив int[] с помощью Stream?
Как перевернуть массив int[] с помощью Stream?
Для int[] можно развернуть элементы декларативно через IntStream, перебирая индексы в обратном порядке. Вариант читается компактнее, но для примитивов уступает обычному циклу по скорости и всегда создаёт новый массив. На собеседовании чаще ждут ручной реверс на месте.
int[] source = {1, 2, 3, 4, 5};
int[] reversed = IntStream.rangeClosed(1, source.length)
.map(i -> source[source.length - i])
.toArray();
System.out.println(Arrays.toString(reversed)); // [5, 4, 3, 2, 1]
5. Как перевернуть List и массив объектов, и есть ли в Java готовый метод для разворота массива?
Как перевернуть List и массив объектов, и есть ли в Java готовый метод для разворота массива?
Для List есть готовый Collections.reverse(), который меняет список на месте. Для массива примитивов готового Arrays.reverse() в стандартной библиотеке нет — пишут реверс вручную циклом или берут ArrayUtils.reverse() из Apache Commons Lang. Массив объектов разворачивают тем же алгоритмом обмена, но через обобщённый метод (дженерики не работают с примитивами, поэтому для int[] нужна отдельная версия). Частые ошибки: цикл до конца массива вместо середины, вызов Collections.reverse() на массиве и Arrays.asList(intArray), который вернёт список из одного элемента — самого массива.
public static <T> void invert(T[] array) {
for (int i = 0; i < array.length / 2; i++) {
T tmp = array[i];
array[i] = array[array.length - i - 1];
array[array.length - i - 1] = tmp;
}
}