我必须将数组中的数字交换'd'次,以便可以向左旋转数组。 'd'是数组的转数。假设数组为1-> 2-> 3-> 4-> 5,并且如果d = 1,则在向左旋转一圈后,数组将为2-> 3-> 4-> 5-> 1。
我已使用以下代码执行上述操作:
for (int rotation = 0; rotation < d; rotation++) {
for (int i = 1; i < a.length; i++) {
int bucket = a[i - 1];
a[i - 1] = a[i];
a[i] = bucket;
}
}
但是该算法的效率太高,可能是O(n ^ d)最坏的情况。如何提高算法效率,尤其是在最坏的情况下?
我正在寻找一种针对该算法的递归方法。我想出了:
public static void swapIt(int[] array, int rotations){
for(int i=1; i<array.length; i++){
int bucket = array[i-1];
array[i-1] = array[i];
array[i] = bucket;
}
rotations--;
if(rotations>0){
swapIt(array,rotations);
}
else{
for(int i=0; i<array.length; i++){
System.out.print(array[i]+" ");
}
}
}
此RECURSIVE算法有效,但效率再次成为问题。不能用于更大的阵列。
答案 0 :(得分:3)
您的算法的复杂度对我来说就像 O(n * d)。
我的方法不是旋转d次,而是旋转d次。
您可以通过以下方式计算元素的目的地:
因此代替了a[i - 1] = a[i];
您可以这样做:
a[(i + a.length - d) % a.length] = a[i];
术语(i + a.length - d) % a.length
表示您总是在时间间隔中获取值:0... a.length-1
说明:
i + a.length - d
始终为正(只要d为<= a.length)
但它可能大于/等于a.length
,这是不允许的。
因此,请注意a.length
的划分。
这样,您就可以为每个i= 0.. a.length-1
获得合适的新职位。
Satyarth Agrahari 提到:
如果d> n,则需要减小d。 d= d % a.length
以确保(i + a.length - d) % a.length
在所需间隔0... a.length-1
中。结果是一样的,因为旋转a.length就像什么都不做。
答案 1 :(得分:1)
要添加@ mrsmith42的答案,您可能应该检查d
是否在1 <= d <= N-1
范围内。您可以将模取为d = d % N