编程之美读书笔记-数组循环移位

来源:互联网 发布:缺德的医生 知乎 编辑:程序博客网 时间:2024/06/10 19:37
题目:设计一个算法,把一个含有N个元素的数组循环右移K位,要求时间复杂度为O(N),且只允许使用两个附加变量。
解析:可以每次将数组中的元素右移一位,循环K次。时间复杂度为O(K*N),不符合题目的要求。仔细观察循环右移的特点,不难发现每个元素右移N位后都会回到自己的位置上。因此右移K位之后的情形,跟右移K%N位之后是一样的。时间复杂度降为O(N^2),仍然不符合题目的要求。假设原数组序列为abcd1234,循环右移4位之后的序列为1234abcd,1234和abcd这两段的位置是不变的。可以把这两段看成两个整体,右移K位的过程就是把数组的两部分交换一下。
1.逆序排列abcd:abcd1234-dcba1234;
2.逆序排列1234:dcba1234-dcba4321;
3.全部逆序:dcba4321-1234abcd。
如图所示,这种方法被形象地称为手摇法。


#include <iostream>  #include <algorithm>  #define MAXN 1010using namespace std;int arr[MAXN];void Reverse(int *arr, int b, int e){for (; b < e; b++, e--) swap(arr[b], arr[e]);}void RightShift(int *arr, int N, int k){k = k%N;Reverse(arr, 0, N - k - 1);Reverse(arr, N - k, N - 1);Reverse(arr, 0, N - 1);}int main(){int N, k;cin >> N >> k;for (int i = 0; i < N; i++) cin >> arr[i];RightShift(arr, N, k);for (int i = 0; i < N; i++) cout << arr[i] << " ";cout << endl;system("pause");}


0 0