Рекурсивно реверсировать массив для определенного диапазона элементов c - PullRequest
1 голос
/ 30 апреля 2020
public static void reverse(ArrayList<Integer> numbers, int start, int end) {
    if (start < end) {
        int temp = numbers.get(start);
        numbers.set(numbers.indexOf(start), numbers.get(end));
        numbers.set(numbers.indexOf(end), temp);
        reverse(numbers, start + 1, end - 1);
    }
}

Я пытаюсь рекурсивно обратить элементы в списке массивов. Однако примеры выходных данных, такие как: [1, 2, 3, 4] из 1-3 возвращает [4, 2, 2, 4] не: [1, 4, 3, 2]

Ответы [ 3 ]

3 голосов
/ 30 апреля 2020

Изменить

numbers.set(numbers.indexOf(start), numbers.get(end));
numbers.set(numbers.indexOf(end), temp);

на

numbers.set(start, numbers.get(end));
numbers.set(end, temp);

start, end - это индексы в списке, где вы хотите поменять значения. Вы не должны звонить indexOf, чтобы получить индекс. indexOf дает вам индекс первого появления значения, которое вы передаете.

1 голос
/ 30 апреля 2020

tl; dr

Вы слишком усердно работаете. Не нужно писать свой рекурсивный метод reverse.

Изменение представления части списка влияет на исходный список.

Collections
.reverse(                                // Re-ordering a sublist view affects the original list.
    numbers                              // Your modifiable list of objects (Integer objects in your case). 
    .subList( 1 , 3 + 1 )                // Specify your desired subset that needs reversing, to get a view backed by the original list. Use zero-based index numbers. Add one as the ending is exclusive.
) ;

List::subList

The результат вызова List::subList - это представление, основанное непосредственно на этой части исходного списка. Если вы измените исходный список, вы измените представление подсписка.

Более важно для нашей цели: если вы измените представление подсписка, вы измените оригинал. Итак, давайте изменим только подпредставление, чтобы повлиять на оригинал.

Конечно, это работает только для модифицируемого List, такого как ArrayList.

Collections.reverse

Чтобы перевернуть список, вызовите служебный метод Collections.reverse.

В этих двух строках кода мы делаем List, возьмите вид на часть этого списка, поменяйте местами элементы в этой части и, таким образом, воздействуйте на исходный список.

List < Integer > numbers = new ArrayList <>( List.of( 1 , 2 , 3 , 4 ) );
Collections.reverse( numbers.subList( 1 , 3 + 1 ) ) ;

Две вещи о методе subList:

  • К сожалению, он принимает аргументы, которые основаны на нулях, а не на порядковых номерах.
  • Полуоткрыто, что означает начало включительно , а окончание исключительное . Поэтому мы должны добавить его в индекс последнего элемента, который мы хотим включить.

Пример использования

Попробуйте этот код еще раз, но добавьте вызовы, чтобы вывести список в консоль.

List < Integer > numbers = new ArrayList <>( List.of( 1 , 2 , 3 , 4 ) );
System.out.println( "numbers = " + numbers );

Collections.reverse( numbers.subList( 1 , 3 + 1 ) ) ;
System.out.println( "numbers = " + numbers );

См. Этот код, запущенный в режиме реального времени на IdeOne.com .

numbers = [1, 2, 3, 4]

числа = [1, 4, 3, 2]

0 голосов
/ 30 апреля 2020

Помимо сравнения значений start и end, вы должны поставить другие проверки, показанные ниже, чтобы избежать IndexOutOfBoundsException:

static void reverse(List<Integer> numbers, int start, int end) {
    if (start > end || start >= numbers.size() || start <= 0 || end >= numbers.size() || end <= 0) {
        return;
    }
    Integer temp = numbers.get(start);
    numbers.set(start, numbers.get(end));
    numbers.set(end, temp);
    reverse(numbers, start + 1, end - 1);
}

@SomeDude уже ответил на остальную часть исправления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...