題目:
定義字符串的左旋轉操作:把字符串前面的若干個字符移動到字符串的尾部。
如把字符串abcdef 左旋轉2 位得到字符串cdefab。請實現字符串左旋轉的函數。
要求時間對長度爲n 的字符串操作的複雜度爲O(n),輔助內存爲O(1)。
分析:如果不考慮時間和空間複雜度的限制,
最簡單的方法莫過於把這道題看成是把字符串分成前後兩部分,
通過旋轉操作把這兩個部分交換位置。
於是我們可以新開闢一塊長度爲n+1 的輔助空間,
把原字符串後半部分拷貝到新空間的前半部分,在把原字符串的前半部分拷貝到新空間的後
半部分。
不難看出,這種思路的時間複雜度是O(n),需要的輔助空間也是O(n)。
把字符串看成有兩段組成的,記位XY。左旋轉相當於要把字符串XY 變成YX。
我們先在字符串上定義一種翻轉的操作,就是翻轉字符串中字符的先後順序。把X 翻轉後
記爲XT。顯然有(XT)T=X。
我們首先對X 和Y 兩段分別進行翻轉操作,這樣就能得到XTYT。
接着再對XTYT 進行翻轉操作,得到(XTYT)T=(YT)T(XT)T=YX。正好是我們期待的結果。
分析到這裏我們再回到原來的題目。我們要做的僅僅是把字符串分成兩段,
第一段爲前面m 個字符,其餘的字符分到第二段。
再定義一個翻轉字符串的函數,按照前面的步驟翻轉三次就行了。
時間複雜度和空間複雜度都合乎要求。
#include<iostream>
#include<string>
using namespace std;
void reverse(string &s,int begin,int end)
{
if(begin<0||end<0)
return;
for(;begin<end;begin++,end--)
{
char temp=s[begin];
s[begin]=s[end];
s[end]=temp;
}
}
void leftrev(string &s,int m)
{
int n=s.size();
if(m>n)
return;
reverse(s,0,m-1);
reverse(s,m,n-1);
reverse(s,0,n-1);
}
int main()
{
string str="abcdefghijklmnopq";
leftrev(str,4);
cout<<str<<endl;
}