题目描述:
定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部,如把字符串abcdef左旋转2位得到字符串cdefab。
请实现字符串左旋转的函数,要求对长度为n的字符串操作的时间复杂度为O(n),空间复杂度为O(1)。
我的解题思路:
1.最简单的思路
拿到这个题目,如果不考虑时间复杂度和空间复杂度的要求,那么我的首选思路是:建立一个缓存数组存储要左旋的字符(如题中的ab),然后直接从c开始,每个字符覆盖左移两个位置的字符(c->a,d->b这样)。最后再把ab依次放到数组的最后。这种思路非常简单,时间复杂度是o(n),但是空间复杂度是o(m),不合题意。
2.改进的思路
由于题目要求空间复杂度为O(1),因此是无法使用额外的内存空间,自然想到必须要通过交换操作而不是覆盖操作来实现旋转。接下来就可以想到博客中所提到的思路二,具体的细节不再多说,自己编写程序如下:
#include <string>
#include <iostream>
using namespace std;
void shift(string & src,int n,int cnt);
void swap(char * a,char * b );
void main()
{
string src("abcdefghijk");
int cnt=3;
//string result;
int n=src.length();
shift(src,n,cnt);
cout << "result is " << src <<endl;
getchar();
}
void shift(string & src,int n,int cnt)
{
char * spoint = &(src[0]);
char * dpoint = spoint+cnt;
while(n>cnt)
{
if(2*cnt<=n)
{
for(int i=0;i<cnt;i++)
swap(spoint+i,dpoint+i);
}
else
{
int r = spoint+n-dpoint;
for(int j=0;j<r;j++)
{
for(int i=cnt+j;i>j;i--)
{
swap(spoint+i,spoint+i-1);
}
}
}
n=n-cnt;
spoint=spoint+cnt;
dpoint=dpoint+cnt;
}
}
void swap(char * a,char * b )
{
char tmp;
tmp=*a;
*a=*b;
*b=tmp;
}
在思考上述问题的时候,也发现可以使用递归的方法去做。对本题而言,递归和循环的思路并无太多区别,都是重复同一种操作而已。
之后的思路四只能用精彩形容。
思路五很奇妙。