因此,对于步长为1,我想要数组:
{1, 2, 3, 4}
成为:
{4, 1, 2, 3}
对于大小为2的步骤,结果将是:
{3, 4, 1, 2}
这是我现在使用的代码:
private static int[] shiftArray(int[] array, int stepSize) {
if (stepSize == 0)
return array;
int shiftStep = (stepSize > array.length ? stepSize % array.length : stepSize);
int[] array2 = new int[array.length];
boolean safe = false;
for (int i = 0; i < array.length; i++) {
if (safe) {
array2[i] = array[i - shiftStep];
}
else {
array2[i] = array[array.length - shiftStep + i];
safe = (i+1) - shiftStep >= 0;
}
}
return array2;
}
代码运行良好,但是可以在不创建辅助数组(上面的代码中是array2)的情况下实现这一点吗?
谢谢!
答案 0 :(得分:11)
您可以在不创建大型数组的情况下执行此操作:
// void return type as it shifts in-place
private static void shiftArray(int[] array, int stepSize) {
// TODO: Cope with negative step sizes etc
int[] tmp = new int[stepSize];
System.arraycopy(array, array.length - stepSize, tmp, 0, stepSize);
System.arraycopy(array, 0, array, stepSize, array.Length - stepSize);
System.arraycopy(tmp, 0, array, 0, stepSize);
}
因此,对于100,000个数组和10的步长,它会创建一个10个元素的数组,将最后10个元素复制到其中,将第一个999,990个元素复制到后面,然后从临时数组复制回< em>开始数组。
答案 1 :(得分:3)
不使用i ++,但是i + = shiftSize和几个循环(它们的数量等于array.length和shifSize的gcd。
然后你只需要一个int作为缓冲区,执行时间几乎相同。
答案 2 :(得分:3)
你可以用几个循环来做,但这并不容易。在这种情况下,使用递归更简单。
public static void main(String... args) {
for (int i = 0; i < 12; i++) {
int[] ints = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
rotateLeft(ints, i);
System.out.println(Arrays.toString(ints));
}
}
public static void rotateLeft(int[] array, int num) {
rotateLeft(array, num, 0);
}
private static void rotateLeft(int[] array, int num, int index) {
if (index >= array.length) return;
int tmp = array[(index + num) % array.length];
rotateLeft(array, num, index + 1);
array[index] = tmp;
}
打印
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1]
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2]
[4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3]
[5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4]
[6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5]
[7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6]
[8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7]
[9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8]
[10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
答案 3 :(得分:2)
是的,有可能,您只需临时存储阵列附加的一个元素。 基本上你想要做的是:
答案 4 :(得分:2)
这未经过测试......
public void rotateByStep(int[] array, int step) {
step = step % array.length;
if (step == 0) {
return;
}
int pos = step;
int tmp = array[0];
boolean inc = array.length % step == 0;
for (int i = 0; i < array.length; i++) {
int tmp2 = array[pos];
array[pos] = tmp;
tmp = tmp2;
pos = (pos + step) % array.length;
if (inc && pos < step) {
array[pos] = tmp;
pos++;
tmp = array[pos];
}
}
}
我试图实施的想法如下:
如果step
不是length
的因子,则从pos
模step
开始递增索引(length
)在length
次迭代后,零将访问每个数组元素。
如果step
是length
的因子,则索引(如上所述递增)将在length / step
次迭代后返回其起始点。但是如果然后增加1,则可以处理从1开始的循环,然后是2,依此类推。在length
次迭代后,我们将访问每个数组元素一次。
当我们循环遍历元素索引时,其余的只是在元素值上晃动...当我们增加到下一个周期时进行一些调整。
其他完整的解决方案的优点是它们更容易理解,但是这个解决方案不需要额外的堆存储(即没有临时数组),并且在array.length
循环迭代中完成工作。
答案 5 :(得分:0)
在n-1次迭代中
#include <stdio.h>
int main(int argc, char **argv) {
int k = 0, x = 0;
int a[] = {-5,-4,-1,0,1,2,30,43,52,68,700,800,9999};
int N = 0, R = 57; /*R = No of rotations*/
int temp = 0, temp2 = 0, start = 0, iter = 0;
x = 0;
temp2 = a[x];
N = sizeof(a) / sizeof(a[0]);
for ( k = 0; k < N - 1; k++) {
x = x + R;
while ( x >= N ) {
x = x - N;
}
temp = a[x];
a[x] = temp2;
temp2 = temp;
if ( x == start ) {
start = start + 1;
x = x + 1;
temp2 = a[x];
}
iter++;
}
a[start] = temp2;
for ( k = 0; k < N; k++) {
printf(" %d", a[k]);
}
printf("\n");
printf("Done in %d iteration\n", iter);
return 0;
}