2010
题目
设将n(n>1)个整数存放到一维数组R中。试设计一个在时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移p(0<p<n)个位置,即将R中的数组由(X0,X1, … Xn-1)变换为(Xp,Xp-1, … Xn-1,X0,X1, … Xp-1)。要求:
(1)给出算法的基本设计思想。
(2)根据设计思想,采用C、C++或JAVA语言描述算法,关键之处给出注释。
(3)说明你所涉及算法的时间复杂度和空间复杂度。
-
暴力解:
- 将不需要移出的元素依次从头填入
- 然后把移出的元素拼接到数组后面
- 时间复杂度o( n )
- 空间复杂度o( p )
#include<iostream> using namespace std; const int n = 10; const int p = 5; void reverse(int* R, int n, int p) { int* arr = new int[n]; //int arr[n] int k = 0; for (int i = p; i < n; i++) { arr[k++] = R[i]; } for (int i = 0; i < p; i++) { arr[k++] = R[i]; } for (int i = 0; i < n; i++) { cout << arr[i] << " "; } } int main() { int R[n] = { 1,2,3,4,5,6,7,8,9,10 }; reverse(R, n, p); }
-
最优解
- 靠转置实现
- 核心就是将收尾两个元素调换位置
- 前面转置
- 后面转置
- 全部转置
- 时间复杂度o(n)
- 空间复杂度o(1)
#include<iostream> using namespace std; const int n = 10; const int p = 5; void reverse(int* arr, int l, int r)//arr是数组首地址 { for (int i = 0; i < (r - l + 1) / 2; i++) { int temp = arr[l + i]; arr[l + i] = arr[r - i]; arr[r - i] = temp; } } int main() { int R[n] = { 1,2,3,4,5,6,7,8,9,10 }; reverse(R, 0, p - 1); reverse(R, p, n - 1); reverse(R, 0, n - 1); for (int i = 0; i < n; i++) { cout << R[i] << " "; } }
- 靠转置实现