如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?
假设原数组序列为abcd1234,要求变换成的数组序列为1234abcd,即循环右移了4位。比较之后,不难看出,其中有两段的顺序是不变的:1234和abcd,可把这两段看成两个整体。右移K位的过程就是把数组的两部分交换一下。变换的过程通过以下步骤完成:
逆序排列abcd:abcd1234 → dcba1234;
逆序排列1234:dcba1234 → dcba4321;
全部逆序:dcba4321 → 1234abcd。
这样就可以线性时间实现右移操作了。
#include <stdio.h>
int a[100];
//反转
void reverse(int *a, int m, int n){
for (int i = m; i <= (m + n) / 2; i++){
int tmp = a[i];
a[i] = a[m + n - i];
a[m + n - i] = tmp;
}
}
int main(){
int n, m;
scanf("%d%d", &n, &m);
m %= n;//由于n可能比m大,而每循环右移n个就回到了原来的位置)
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
reverse(a, 0, n-m-1);
reverse(a, n-m, n-1);
reverse(a, 0, n-1);
for (int i = 0; i < n; i++)
printf("%d%s", a[i], (i-n+1?" ":"\n"));
return 0;
}