今天是2014.06.16,从今天开始,我将参看july的博客进行算法的学习及练习,在此只是做一个记录。
————————————分割线—————————————————————————————————————————————
001 字符串旋转
描述:
定义字符串的向左旋转的操作:把一个字符串的前面若干个字符移动到字符串的尾部,如abcde将前两个字符移动到尾部,则有cdeab。
实现字符串左旋函数,对长度为n的字符串的时间复杂度为O(n),空间复杂度为O(1)。
解法:
方案一:暴力法:硬移,即一位一位的移动,时间复杂度O(m*n),空间复杂度O(1)。
void leftShitOne(char *s,int n)
{
char t = s[0];
for(int i=1;i<n;i++)
{
s[i-1]=s[i];
}
s[n-1] = t;
}
void votate1(char *s, int n, int m)
{;
for(int i=0;i<m;i++)
{
leftShitOne(s,n);
}
}
方案二:将n个字符分成n/m取天棚段,如果n/m是整数,则将前m个字符向后移动n/m位即可,否则,先将前m个字符向后移动n/m位,然后依次将剩下的n%m个字符与这m个字符进行移位。时间复杂度O(n),空间复杂度O(1)。
void votate2(string &str,int m)
{
if(str.length()==0 || m < 0)
return;
int p1=0,p2=m;
int n = str.length();
int k = (n-m)-n%m;
while(k--)
{
swap(str[p1],str[p2]);
p1++;
p2++;
}
int r = n-p2;
while(r--)
{
int i=p2;
while(i>p1)
{
swap(str[i],str[i-1]);
i--;
}
p1++;
p2++;
}
}
方案三:散步反转法,将字符串分成两个部分,前m个字符和后n-m个字符,先对前m个字符进行翻转,在对后n-m个字符进行翻转,最后对整个字符串进行翻转
void reverse(string &str,int start,int end)
{
while(start<end)
{
swap(str[start],str[end]);
start++;
end--;
}
}
void votate3(string &str,int m)
{
int n = str.length();
reverse(str,0,m-1);
reverse(str,m,n-1);
reverse(str,0,n-1);
}
相似题型:
1.编写程序,在原字符串中把字符串尾部的m个字符移动到字符串的头部,要求:长度为n的字符串操作时间复杂度为O(n),空间复杂度为O(1)。 例如,原字符串为”Ilovebaofeng”,m=7,输出结果为:”baofengIlove”。
解决方案:与左旋相似,三步翻转法
2.单词翻转。输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变,句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。例如,输入“I am a student.”,则输出“student. a am I”。
解决方案:以空格为分界,对每个单词进行翻转,然后翻转整个句子。