最近,我使用杂耍算法了解了线性时间内的数组旋转。这是有关数组向左旋转的代码段。
void ArrayRotate (int A[], int n, int k)
{
int d=-1,i,temp,j;
for(i=0;i<gcd(n,k);i++)
{
j=i;
temp=A[i];
while(1)
{
d=(j+k)%n;
if(d==i)
break;
A[j]=A[d];
j=d;
}
A[j]=temp;
}
}
但是现在我被困在如何使用这种杂耍算法向正确方向旋转数组上。
1,2,3,4,5 (given array)
5,1,2,3,4 (after 1 right rotation)
(我已经使用蛮力法和逆向法解决了这个问题。)
答案 0 :(得分:1)
void ArrayRotate(int A[], int n, int k) {
int d = -1, i, temp, j;
int g = gcd(n, k);
for (i = 0; i < g; ++i) {
j = i;
temp = A[i];
while (true) {
d = (j + k) % n;
if (d == i) {
break;
}
A[j] = A[d];
j = d;
}
A[j] = temp;
}
}
还请注意,我在循环条件外进行了gcd计算。从技术上讲,它不会影响复杂性,但是只计算一次gcd就足够了。
要向右旋转数组k
次,只需向左旋转n - k
次。
void ArrayRotateRight(int A[], int n, int k) {
ArrayRotate(A, n, n - k);
}
或将第8行更改为d = (j - k + n) % n;
答案 1 :(得分:0)
不确定是作为智力活动还是针对生产代码,但是对于生产代码,请使用STL rotate
算法:
#include<iostream>
#include<algorithm>
using namespace std;
void display(int* a, int length)
{
for (int i = 0; i < length; ++i)
cout << a[i] << " ";
cout << endl;
}
int main()
{
const int len = 5;
int arr[] = { 1,2,3,4,5 };
display(arr, len);
rotate(arr, arr + 1, arr + len); // arr + x means left by x
display(arr, len);
rotate(arr, arr + len - 1, arr + len); // arr + len - x means right by x
display(arr, len);
}