Вот поворот на месте (не использует второй массив), с O (a.length) сложностью по времени. В моей системе (Intel 3770K 3,5 ГГц) он может вращать массив элементов размером 2 ^ 28 = 268 435 456 в .17 (поворот 76) до 0,85 секунд (поворот 1). Перестановки выполняются в последовательных последовательностях доступа, что облегчает кеширование.
// rotate in place
public static void rolip(int[] a, int r){
r = r % a.length;
if(r == 0)
return;
int t;
int n = a.length - r;
int i = 0;
int j;
while(true){
if(r <= n){ // shift left r places
for(j = i+r; i < j; i++){
t = a[i]; // swap(a[i], a[i+r])
a[i] = a[i+r];
a[i+r] = t;
}
n -= r;
if(n == 0)
break;
} else { // shift right n places
i += r;
for(j = i+n; i < j; i++){
t = a[i]; // swap(a[i], a[i-n])
a[i] = a[i-n];
a[i-n] = t;
}
i -= n+r;
r -= n;
if(r == 0)
break;
}
}
}
Простое вращение с использованием второго массива. В моей системе (Intel 3770K 3,5 ГГц) он может повернуть массив элементов размером 2 ^ 28 = 268 435 456 за 0,11–0,5 секунды.
public static void rol(int[] a, int r){
r = r % a.length;
if(r == 0)
return;
int n = a.length - r;
int i;
int j;
if(r <= n){ // if left rotate
int[] b = new int[r]; // save elements
for(j = 0; j < r; j++)
b[j] = a[j];
for(i = 0; i < n; i++) // shift elements
a[i] = a[j++];
for(j = 0; j < r; j++) // copy saved elements
a[i++] = b[j];
} else { // else right rotate
int[] b = new int[n]; // save elements
i = 0;
for(j = r; j < a.length; j++)
b[i++] = a[j];
i = j-1; // shift elements
for(j = i-n; j >= 0; j--)
a[i--] = a[j];
for(j = 0; j < n; j++) // copy saved elements
a[j] = b[j];
}
}