题目描述:
定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部,如把字符串abcdef左旋转2位得到字符串cdefab。
定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部,如把字符串abcdef左旋转2位得到字符串cdefab。
请实现字符串左旋转的函数,要求对长度为n的字符串操作的时间复杂度为O(n),空间复杂度为O(1)。
思路一、暴力移位法
#include<iostream>
using namespace std;
void leftshiftone(char A[],int len)
{
char temp=A[0];
for (int i=0;i<len-1;i++)
{
A[i]=A[i+1];
}
A[len-1]=temp;
}
void leftshift(char A[],int len,int m_pos)
{
while (m_pos--)
{
leftshiftone(A,len);
}
}
int main()
{
char a[]={'a','b','c','d','e'};
int i;
for(i=0;i<sizeof(a)/sizeof(char);i++)
cout<<a[i]<<" ";
cout<<endl;
leftshift(a,sizeof(a)/sizeof(char),2);
for(i=0;i<sizeof(a)/sizeof(char);i++)
cout<<a[i]<<" ";
cout<<endl;
system("pause");
return 0;
}
思路二、三步翻转法
将一个字符串分成两部分,X和Y两个部分,在字符串上定义反转的操作X^T,即把X的所有字符反转(如,X="abc",那么X^T="cba"),那么我们可以得到下面的结论:(X^TY^T)^T=YX。
对于abcdef 这个例子来说,若要让def翻转到abc的前头,那么只要按下述3个步骤操作即可:
1、首先分为俩部分,X:abc,Y:def;
2、X->X^T,abc->cba, Y->Y^T,def->fed。
3、(X^TY^T)^T=YX,cbafed->defabc,即整个翻转。
#include<iostream>
using namespace std;
void invert(char *begin,char* end)
{
char temp;
while (begin<end)
{
temp=*begin;
*begin=*end;
*end=temp;
begin++;
end--;
}
}
void shift(char* b,int len,int m)
{
invert(b,b+m-1);
invert(b+m,b+len-1);
invert(b,b+len-1);
}
int main()
{
char q[]="abcdefg";//不能通过指针q修改字符串常量
char *a=q;
size_t i;
for(i=0;i<strlen(a);i++)
cout<<*(a+i)<<" ";
cout<<endl;
size_t length=strlen(a);
shift(a,length,2);
for(i=0;i<strlen(a);i++)
cout<<*(a+i)<<" ";
cout<<endl;
system("pause");
return 0;
}
类似问题
1、链表翻转。给出一个链表和一个数k,比如链表1→2→3→4→5→6,k=2,则翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→5→6,用程序实现。
2、编写程序,在原字符串中把尾部m个字符移动到字符串的头部,要求:长度为n字符串操作时间复杂度为O(n),空间复杂度为O(1)。 如:原字符串为”Ilovebaofeng”,m=7,输出结果:”baofengIlove”。