描述
设将n(n>1)个整数存放到一维数组R中。试设计一个在时间和空间两方面都尽可能高效的算法,将R中保存的序列循环左移p(0<p<n)个位置,即将R中的数据由(x0, x1…, xn-1)变换为(xp,xp+1,…,xn-1,x0,x1,…,xp-1)。
输入
多组数据,每组数据有三行。第一行为一个整数n,代表数组R中有n个元素。第二行为数组R中的n个元素(元素之间用空格分隔)。第三行为一个整数p,代表将R中的序列循环左移p个位置。当n等于0时,输入结束。
输出
每组数据输出一行,为移动后的数组R中所存放的序列。每两个数之间用空格分隔。 输入样例
输入样例 1
5 1 2 3 4 5 1 6 -1 2 3 2 4 3 3 0
输出样例 1
2 3 4 5 1 2 4 3 -1 2 3
因为要求尽量降低时空复杂度,
将数组R循环左移p位后,前p个数一定移动到后面,而后n-p移动到前面,因此可先将数组R逆置,然后再将R中前n-p个元素原地逆置,再将后p个元素原地逆置
用REVERse函数来进行实现。这样,上述算法中三个Reverse函数的时间复杂度分别为O(n/2)、O((n-p)/2)和O(p/2),故所设计的算法的时间复杂度为O(n),空间复杂度为O(1)。最为快捷
#include<iostream> using namespace std; void Reverse(int r[], int begin, int end) { int i, temp; for (i = 0; i < (end - begin + 1) / 2; i++) { temp = r[begin + i]; r[begin + i] = r[end - i]; r[end - i] = temp; } } int main() { while (1) { int r[10000]; int n,position; cin >> n; if (n == 0) break; for (int i = 0; i < n; i++) cin >> r[i]; cin >> position; Reverse(r, 0, n - 1); Reverse(r, 0, n - 1 - position); Reverse(r, n - position, n - 1); for (int i = 0; i < n ; i++) { if (i == n - 1) cout << r[i] << endl; else cout << r[i] << ' '; } } }