题目:给定一个字符串,将字符串前面若干个字符移到字符串尾部。如,将“abcdef”的前3个字符移到尾部,变成“defabc”。
void LeftRotateString(char* s, int n, int m)
{
}
将长度为n的字符串s中的前m个字符移到尾部
解法一:蛮力移位
每次移动一个字符到尾部,移动m次;而每次将第一个字符移到尾部时,只能是将后面的字符一个个往前挪,所以单次的时间复杂度O(n),总时间复杂度O(m*n)
解法二:三步反转
这是字符串反转的常用方法。
第一步:先将“abcdef”变成“fedcba”
第二步:将其中“fed”反转为“def”
第三部:将“cba”反转为“abc”
或者:
第一步:先将“abc”变成“cba”
第二步:将其中“def”反转为“fed”
第三部:将“cbafed”反转为“defabc”
时间复杂度O(n),空间复杂度O(1)
解法三:逐步定位
用下标index从左到右遍历,每遍历到一个字符,就把该字符放到应该放的位置,用一个字符tmp存储当前被挤出来的字符
以“abcdef”为例,m =2, index从0开始,到m-1为止(因为此时m后面的字符应该都放到了该放的位置),a应该放到c的位置,所以变为“0badef”,挤出来的字符tmp是c,此时index增至1;c应该放到e的位置,所以变成“0badcf”,挤出来的tmp是e;e应该放到原来a的位置,所以变为“ebadcf”;此时tmp为0了,所以继续index的遍历,到b,b应该放到d的位置,所以变为“e0abef”,tmp是d,index为2;而d应该放到f的位置,所以变为“e0abcd”,f应该放到0的位置,所以变为“efabcd”此时tmp为0,index = m,终止。
因为这种方法是直接操作字符串,只用了有限的外部变量,所以时间复杂度O(n),空间复杂度O(1)
参考 《编程之法》