here is a O(nlogn) solution, Rotate can be further optimized.
public class InterleaveShuffle {
public static void main(String argv[]) {
int [] arr = {1,2,3,4,5,100,200,300,400,500};
InplaceInterleave(arr, 0, arr.length - 1);
InplaceRestore(arr, 0, arr.length - 1);
}
static void Reverse(int A[], int left, int right)
{
while (left < right) {
int tmp = A[left];
A[left++] = A[right];
A[right--] = tmp;
}
}
static void Rotate(int A[], int left, int right, int piv) {
if(piv != left){
Reverse(A, left, piv - 1);
Reverse(A, piv, right);
}
Reverse(A, left, right);
}
static void InplaceInterleave(int A[], int left, int right) {
if ((right - left) <= 1) return;
int mid = left + (right - left) / 2;
int halfSize = (right - left + 1) / 2;
int leftMid = left + (mid - left) / 2;
int rightMid = (right + mid + 1) / 2;
Rotate(A, leftMid + 1, rightMid, mid + 1);
InplaceInterleave(A, left, mid + halfSize % 2);
InplaceInterleave(A, mid + 1 + halfSize % 2, right);
}
static void InplaceRestore(int A[], int left, int right) {
if ((right - left) <= 1) return;
int mid = left + (right - left) / 2;
int halfSize = (right - left + 1) / 2;
int leftMid = left + (mid - left) / 2;
int rightMid = (right + mid + 1) / 2;
InplaceRestore(A, left, mid + halfSize % 2);
InplaceRestore(A, mid + halfSize % 2 + 1, right);
Rotate(A, leftMid + 1, rightMid, mid + halfSize % 2 +1);
}
}