Java - 旋转数组

时间:2014-10-28 14:02:08

标签: java arrays rotation

所以我们的目标是将数组中的元素旋转a次。 举个例子;如果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是变量我不确定这是最好的解决方案。 提前谢谢。

15 个答案:

答案 0 :(得分:26)

为您的代码添加模数组长度:

// 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进行复制,这样就不会覆盖您以后需要的值。

答案 1 :(得分:12)

如果你不想重新发明轮子(也许这是一个练习,但可以很好地了解),你可以使用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]

答案 2 :(得分:6)

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--;
    }
}

答案 3 :(得分:1)

我认为最快的方法是使用本地方法System.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较小时,您可以减少内存使用量。

答案 4 :(得分:1)

另一种方法是使用System.arraycopy进行复制。

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

答案 5 :(得分:1)

int[] rotate(int[] array, int r) {
    final int[] out = new int[array.length];
    for (int i = 0; i < array.length; i++) {
        out[i] = (i < r - 1) ? array[(i + r) % array.length] : array[(i + r) % array.length];
    }
    return out;
}

答案 6 :(得分:1)

以下rotate方法的行为将与Collections类中的rotate方法与List接口中的subList方法结合使用完全相同,即rotate(n, fromIndex, toIndex, dist),其中n是一个整数数组将给出与 Collections.rotate (Arrays.asList (n).subList (fromIndex, toIndex), dist) 相同的结果,其中 n 是一个整数数组。

首先创建一个交换方法:

public static void swap (int[] n, int i, int j){

   int tmp = n[i];
   n[i] = n[j];
   n[j] = tmp;
}

然后创建旋转方法:

public static void rotate (int[] n, int fromIndex, int toIndex, 
int dist){

   if(fromIndex > toIndex)

      throw new IllegalArgumentException ("fromIndex (" + 
         fromIndex + ") > toIndex (" + toIndex + ")");

   if (fromIndex < toIndex){

      int region = toIndex - fromIndex;
      int index;

      for (int i = 0; i < dist % region + ((dist < 0) ? region : 0); 
              i++){

         index = toIndex - 1;
     
         while (index > fromIndex)

            swap (n, index, --index);
       }
   }
}

答案 7 :(得分:0)

问题:https://www.hackerrank.com/challenges/ctci-array-left-rotation
方案: 这就是我尝试使用复杂度为o(n)

的arrayLeftRotation方法
  • 从k索引循环到(length-1)
  • 第2次0到第k次索引

    public static int [] arrayLeftRotation(int [] a,int n,int k){
        int [] resultArray = new int [n];
        int arrayIndex = 0;
        //将在此循环中填充第一个n-k索引     for(int i = k; i         resultArray [arrayIndex] = a [i];
            arrayIndex ++;
        }
        //将在此循环中填充第二个k索引     for(int j = arrayIndex; j&lt;(arrayIndex + k); j ++){
            resultArray [J] = A [J =(N-K)];
        }
        return resultArray;
    }

答案 8 :(得分:0)

用方法包装的Java解决方案:

Places

答案 9 :(得分:0)

For Left旋转非常简单

取数组长度与要移位的位置数之间的差异。

例如

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);

//打印输出

答案 10 :(得分:0)

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] + " ");
        }
    }

}

答案 11 :(得分:0)

ruby​​ 中,可以在一行中旋转阵列。

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

答案 12 :(得分:0)

问题:旋转给定距离的数组。 方法1: 将int数组转到ArrayList。然后使用Collections.rotate(list,distance)。

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
}

答案 13 :(得分:0)

时间复杂度= O(n)

空间复杂度= O(1)

算法从数组的第一个元素(newValue)开始,并将其放置在旋转之后的位置(newIndex)。在newIndex处的元素变为oldValue。之后,将oldValue和newValue交换。

此过程重复长度时间。

该算法基本上会在数组周围反弹,从而将每个元素放置在新位置。

unsigned int computeIndex(unsigned int len, unsigned int oldIndex, unsigned int times) {
    unsigned int rot = times % len;
    unsigned int forward = len - rot;

    // return (oldIndex + rot) % len; // rotating to the right
    return (oldIndex + forward) % len; // rotating to the left
}

void fastArrayRotation(unsigned short *arr, unsigned int len, unsigned int rotation) {
    unsigned int times = rotation % len, oldIndex, newIndex, length = len;
    unsigned int setIndex = 0;
    unsigned short newValue, oldValue, tmp;

    if (times == 0) {
        return;
    }

    while (length > 0) {
        oldIndex = setIndex;
        newValue = arr[oldIndex];
        while (1) {
            newIndex = computeIndex(len, oldIndex, times);
            oldValue = arr[newIndex];
            arr[newIndex] = newValue;

            length--;

            if (newIndex == setIndex) { // if the set has ended (loop detected)
                break;
            }

            tmp = newValue;
            newValue = oldValue;
            oldValue = tmp;

            oldIndex = newIndex;
        }
        setIndex++;
    }
}

答案 14 :(得分:0)

以下例程在Java中旋转数组:

public static int[] rotateArray(int[] array, int k){
    int to_move = k % array.length;
    if(to_move == 0)
      return array;
    for(int i=0; i< to_move; i++){
      int temp = array[array.length-1];
      int j=array.length-1;
      while(j > 0){
        array[j] = array[--j];
      }
      array[0] = temp;
    }
    return array;
 }