字串相關演算法1-字串旋轉

deepwzh發表於2017-04-14

給你一串字串,如何實現將將首部k個字元移動到字串後邊而不改變其他字元的順序?

最容易想到的是,我們可以將需要移動的字元一個一個地移動到字串的尾部。對於每次移動我們只需要一個變數記錄第一個字元,後邊字元往前移動就好了

這裡不給出這種實現的程式碼。

複雜度分析:長度為n的字串,假如需要移動m個字元到字串末尾,那麼總共需要m x n 次操作,時間複雜度為O(mn)

我們僅需要一個變數儲存第一個字元位置,空間複雜度為O(1)

 

有沒有更高效的演算法呢?

基於這樣的事實:一個字串翻轉兩次後與原來的字串是相同的。

因此我們可以對字串進行這樣一個操作,對需要移動的字元子串和不需要移動的字元子串分開處理:

首先對兩個子串翻轉一次,此時每個子串間的相對位置是不變得

然後對整個字串再進行翻轉,對於每個字元子串而言由於翻轉了兩次,與原來字元字串是一致的;整體進行翻轉,字元子串相對位置改變一次,至此我們得到了符合要求的結果。

程式碼如下:

 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)

 

相關文章