将一个n元一维向量向左旋转i个位置。例如,当n=8且i=3时,向量abcdefgh旋转为defghabc。简单的代码使用一个n元的中间向量在n步内完成该工作。你能否仅使用数十个额外字节的存储空间,在正比于n的时间内完成向量的旋转?(《编程珠玑》第二章)
“移动x[0]到临时变量t,然后移动x[i]至x[0],x[2i]至x[i],依此类推(将x中的所有下标对n取模),直至返回到取x[0]中的元素,此时改为从t取值然后终止过程。如果该过程没有移动全部元素,就从x[1]开始再次进行移动,直到所有的元素都已经移动为止。”遍历次数为GCD(n,i)
public static int GCD(int m, int n) {//辗转相除求最大公约数
while (m % n != 0) {
int temp = m % n;
m = n;
n = temp;
}
return n;
}
public static void acrobatics(int n, int i, int[] args) {
int gcd = GCD(n, i);
int current = 0, temp = 0;
while (gcd >= 0) {
temp = args[current];
while (current + i < n) {
args[current] = args[current + i];
current = current + i;
}
args[current] = temp;
current = (current + i) % (n - 1);
gcd--;
}
for (int j = 0; j < args.length; j++)
System.out.println(args[j]);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO 自动生成的方法存根
int[] a = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
acrobatics(8, 4, a);
}