So the goal is to rotate the elements in an array right a
times.
As an example; if a==2
, then array = {0,1,2,3,4}
would become
Question : Rotate array given a specific distance . Method 1 : Turn the int array to ArrayList. Then use 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
}
Time Complexity = O(n)
Space Complexity = O(1)
The algorithm starts with the first element of the array (newValue) and places it at its position after the rotation (newIndex). The element that was at the newIndex becomes oldValue. After that, oldValue and newValue are swapped.
This procedure repeats length times.
The algorithm basically bounces around the array placing each element at its new position.
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++;
}
}
In case you don't want to reinvent the wheel (maybe it's an exercise but it can be good to know), you can use Collections.rotate
.
Be aware that it requires an array of objects, not primitive data type (otherwise you'll swap arrays themselves in the list).
Integer[] arr = {0,1,2,3,4};
Collections.rotate(Arrays.asList(arr), 2);
System.out.println(Arrays.toString(arr)); //[3, 4, 0, 1, 2]
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;
}
Following routine rotates an array in 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;
}
I think the fastest way would be using System.arrayCopy() which is native method:
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);
It also reuses existing array. It may be beneficial in some cases.
And the last benefit is the temporary array size is less than original array. So you can reduce memory usage when a
is small.