Java-вращающийся массив

таким образом, цель состоит в том, чтобы повернуть элементы в массиве вправо a раза. В качестве примера; if a==2, потом array = {0,1,2,3,4} станет array = {3,4,0,1,2}

вот что у меня есть:

for (int x = 0; x <= array.length-1; x++){
    array[x+a] = array[x];
}

однако это не учитывает, когда [x+a] больше, чем длина массива. Я читал, что я должен хранить те, которые больше в другом массиве, но видя как a переменной я не уверен, что это лучшее решение. Спасибо заранее.

11 ответов


добавьте длину массива по модулю в код:

// create a newArray before of the same size as array

// copy
for(int x = 0; x <= array.length-1; x++){
  newArray[(x+a) % array.length ] = array[x];
}

вы также должны создать новый Array для копирования, чтобы вы не перезаписывали значения, которые вам понадобятся позже.


Если вы не хотите изобретать колесо (может быть, это упражнение, но это может быть полезно знать), вы можете использовать Collections.rotate.

имейте в виду, что для этого требуется массив объектов, а не примитивный тип данных (иначе вы поменяете сами массивы в списке).

Integer[] arr = {0,1,2,3,4};
Collections.rotate(Arrays.asList(arr), 2);
System.out.println(Arrays.toString(arr)); //[3, 4, 0, 1, 2]

Arraycopy-дорогостоящая операция, как по времени, так и по памяти. Это был бы эффективный способ повернуть массив без использования дополнительного пространства, такого как принятый ответ.

public void rotate(int[] nums, int k) { // k = 2
    k %= nums.length;
    // {0,1,2,3,4}

    reverse(nums, 0, nums.length - 1); // Reverse the whole Array
    // {4,3,2,1,0}

    reverse(nums, 0, k - 1); // Reverse first part (4,3 -> 3,4)
    // {3,4,2,1,0}

    reverse(nums, k, nums.length - 1); //Reverse second part (2,1,0 -> 0,1,2)
    // {3,4,0,1,2}
}

public void reverse(int[] nums, int start, int end) {
    while (start < end) {
        int temp = nums[start];
        nums[start] = nums[end];
        nums[end] = temp;
        start++;
        end--;
    }
}

другой способ-копирование с


Я думаю, что самый быстрый способ будет использовать система.arrayCopy() который является родным методом:

int[] tmp = new int[a];
System.arraycopy(array, array.length - a, tmp, 0, a);
System.arraycopy(array, 0, array, a, array.length - a);
System.arraycopy(tmp, 0, array, 0, a);

он повторно использует существующий массив. В некоторых случаях это может оказаться полезным. И последнее преимущество-размер временного массива меньше исходного массива. Таким образом, вы можете уменьшить использование памяти, когда a мал.


решение Java, завернутое в метод:

public static int[] rotate(final int[] array, final int rIndex) {
    if (array == null || array.length <= 1) {
        return new int[0];
    }

    final int[] result = new int[array.length];
    final int arrayLength = array.length;

    for (int i = 0; i < arrayLength; i++) {
        int nIndex = (i + rIndex) % arrayLength;
        result[nIndex] = array[i];
    }
    return result;
}

для левого поворота его очень просто

возьмите разницу между длиной массива и количеством позиций для сдвига.

int k = 2;
int n = 5;

int diff = n - k;

int[] array = {1, 2, 3, 4, 5};
int[] result = new int[array.length];
System.arraycopy(array, 0, result, diff, k);
System.arraycopy(array, k, result, 0, diff);

// печати


вопрос:https://www.hackerrank.com/challenges/ctci-array-left-rotation
Решение : Вот как я попробовал метод arrayLeftRotation со сложностью o (n)

  • цикл один раз от индекса k до (длина-1)
  • 2-й раз для индекса от 0 до kth

    публичный статический тип int[] arrayLeftRotation(тип int[] а, инт Н тип int к) {
    int[] resultArray = новый int[n];
    инт сумма значений arrayindex = 0;
    // первые индексы n-k будет заполнен в этом цикле
    для(int i = k; i resultArray[arrayIndex] = a[i];
    сумма значений arrayindex++;
    }
    // 2nd K индексы будут заполнены в этом цикле
    для(Int J В=сумма значений arrayindex ; к resultArray[j]=a[j-(n-k)];
    }
    возвращение resultArray;
    }


package com.array.orderstatistics;

import java.util.Scanner;

public class ArrayRotation {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int r = scan.nextInt();
        int[] a = new int[n];
        int[] b = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = scan.nextInt();
        }
        scan.close();

        if (r % n == 0) {
            printOriginalArray(a);
        } else {
            r = r % n;
            for (int i = 0; i < n; i++) {
                b[i] = a[(i + r) < n ? (i + r) : ((i + r) - n)];
                System.out.print(b[i] + " ");
            }
        }
    }

    private static void printOriginalArray(int[] a) {
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + " ");
        }
    }

}

на Рубин вращение массива может быть возможно в одной строке.

def array_rotate(arr)
   i, j = arr.length - 1, 0
   arr[j],arr[i], i, j = arr[i], arr[j], i - 1, j + 1 while(j<arr.length/2)
   puts "#{arr}"
end

вопрос: Поверните массив на определенное расстояние . Способ 1 : Поверните массив int в ArrayList. Затем используйте коллекции.поворот (список, расстояние).

class test1 {
    public static void main(String[] args) {

        int[] a = { 1, 2, 3, 4, 5, 6 };

        List<Integer> list = Arrays.stream(a).boxed().collect(Collectors.toList());

        Collections.rotate(list, 3);
        System.out.println(list);//[4, 5, 6, 1, 2, 3]

    }// main
}