題目描述
一個數組A中存有N(N>0)個整數,在不允許使用另外數組的前提下,將每個整數循環向右移M(M>=0)個位置,即將A中的數據由(A0 A1……AN-1)變換為(AN-M …… AN-1 A0 A1……AN-M-1)(最后M個數循環移至最前面的M個位置)。如果需要考慮程序移動數據的次數盡量少,要如何設計移動的方法?
輸入描述:
每個輸入包含一個測試用例,第1行輸入N ( 1<=N<=100)、M(M>=0);第2行輸入N個整數,之間用空格分隔。
輸出描述:
在一行中輸出循環右移M位以后的整數序列,之間用空格分隔,序列結尾不能有多余空格。
輸入例子:
6 2
1 2 3 4 5 6
輸出例子:
5 6 1 2 3 4
1 int size,count; 2 cin >> size >> count; 3 int a[200] ={0}; 4 int nums = count%size; 5 for(int i=0;i<size;++i) 6 { 7 cin >> a[i]; 8 if(nums == size) 9 nums = 0; 10 a[100+(nums++)] = a[i]; 11 } 12 for(int i=0;i<size;++i) 13 cout << a[i+100] << ' ';
之前這樣寫的,直接定義一個200的數組,把數組后移到后半邊的數組里。但是還是借助了之外的內存。
由於有上邊紅字限制。在一個數組里邊移動元素,勢必會覆蓋掉當前位置的元素,借助於其他內存保存這些即將被覆蓋的元素又是不合法的。所以這里我們需要另辟蹊徑,采用三次reverse操作,實現“移動”,時間空間復雜度都不超過O(n)。
原理如圖所示:
數組的倒置操作也很簡單,頭尾指針指向的值互換,直至兩個指針相交。
AC代碼:
#include <iostream> using namespace std; class Solutions{ public: void reverse(int arr[],int prev,int back) { int tmp; while(prev<back) { tmp = arr[back]; arr[back] = arr[prev]; arr[prev] = tmp; ++prev; --back; } } void print(int arr[],int prev,int back) { for(int i=prev;i<back;++i) { cout << arr[i]; if(i!=back-1) cout << ' '; } } }; int main() { Solutions s; int size,number; cin >> size >> number; int a[100]; for(int i=0;i<size;++i) cin >> a[i]; number = number%size; s.reverse(a,0,size-1-number); s.reverse(a,size-number,size-1); s.reverse(a,0,size-1); s.print(a,0,size); }