左旋轉字符串(字符串)題目:定義字符串的左旋轉操作:把字符串前面的若干個字符移動到字符串的尾部。如把字符串abcdef左旋轉2位得到字符串cdefab。請實現字符串左旋轉的函數。要求時間對長度爲n的字符串操作的複雜度爲O(n),輔助內存爲O(1)。
思路: 由於兩個要求,導致編碼很麻煩了, 思路就是成段的和相鄰的字符交換
abcdef 2
那麼就用ab 和 cd交換變成 cdabef
再用ab和 ef交換 變成 cdefab ,就完成了
但是出現abcdefg 3
abc 和def 交換變成 defabcg
但是這個時候abc 和g沒法交換了, 那麼我們就反着旋轉就ok了, 比如 讓g 和 c交換變成 abgc
g 和b交換變成agbc,
g和a交換變成gabc;就達到目的了
編碼的時候注意交換的方向隨着能否交換而不停的改變
abcdef 2
第一次remain = (6 - 2) - 2 = 2
最終當remain == 0的時候停止循環就行了
#include <cstring>
#include <cstdio>
using namespace std;
template<class T>
void swap(T &x, T &y)
{
char tmp;
tmp = x;
x = y;
y = tmp;
}
void leftToRight(char s[], int start, int len)
{
for(int i = start; i < len + start; i++)
{
swap(s[i], s[i + len]);
}
}
void rightToLeft(char s[], int start, int len)
{
for(int i = start; i > start - len; i--)
swap(s[i], s[i - len]);
}
int solve(char s[], int m) // O(1)的空間複雜度,o(n)的時間複雜度, 旋轉字符串
{
const int len = strlen(s);
int remain = len - m;
int i = 0;
bool dir = true; //朝右
while(remain)
{
if(dir)
{
if(m <= remain)
{
remain -= m;
leftToRight(s, i, m);
i += m;
}
else
{
dir = !dir;
i = i + m + remain - 1;
swap(m, remain);
}
}
else
{
if(m <= remain)
{
remain -= m;
rightToLeft(s, i, m);
i -= m;
}
else
{
dir = !dir;
i = i - remain - m + 1;
swap(m, remain);
}
}
}
for(int i = 0; i < len; i++)
printf("%c", s[i]);
puts("");
return 0;
}
int main()
{
char s[] = "abcdefgabcdeft";
solve(s, 4);
return 0;
}
當我寫完程序後發現時間空間複雜度多了m, 更不好的是編碼麻煩; 然後我就發現網上有一個更牛逼的解法
abcdef 2
第一步: ba
第二步: fedc
然後見可以bafedc
最後就cdefab
這個相對於第一種方法太好編碼了就略了