Как перевернуть (развернуть) массив в Java - Вопросы

Всего: 5 вопросов

1. 

Как перевернуть массив в 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[] можно развернуть элементы декларативно через 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 есть готовый 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;
    }
}
Страница 1 из 1