給你一串字符串,如何實現將將首部k個字符移動到字符串後邊而不改變其餘字符的順序?ios
最容易想到的是,咱們能夠將須要移動的字符一個一個地移動到字符串的尾部。對於每次移動咱們只須要一個變量記錄第一個字符,後邊字符往前移動就行了算法
這裏不給出這種實現的代碼。spa
複雜度分析:長度爲n的字符串,假如須要移動m個字符到字符串末尾,那麼總共須要m x n 次操做,時間複雜度爲O(mn)code
咱們僅須要一個變量存儲第一個字符位置,空間複雜度爲O(1)blog
有沒有更高效的算法呢?ci
基於這樣的事實:一個字符串翻轉兩次後與原來的字符串是相同的。字符串
所以咱們能夠對字符串進行這樣一個操做,對須要移動的字符子串和不須要移動的字符子串分開處理:string
首先對兩個子串翻轉一次,此時每一個子串間的相對位置是不變得io
而後對整個字符串再進行翻轉,對於每一個字符子串而言因爲翻轉了兩次,與原來字符字串是一致的;總體進行翻轉,字符子串相對位置改變一次,至此咱們獲得了符合要求的結果。class
代碼以下:
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 void RevString(char * s, int from, int to){ 5 while(from < to){ 6 swap(s[from++], s[to--]); 7 } 8 } 9 void LeftRotateString(char *s, int n, int k){ 10 RevString(s, 0, k - 1); 11 RevString(s, k, n - 1); 12 RevString(s, 0, n - 1); 13 } 14 int main(){ 15 char s[1000]; 16 int k; 17 while(cin >> s >> k){ 18 LeftRotateString(s, strlen(s), k); 19 cout << s << endl; 20 } 21 return 0; 22 }
複雜度分析:長度爲n的字符串,每一個字符串翻轉了兩次,時間複雜度爲O(n)