剑指Offer-数据结构 02. 左旋字符串
Q: 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
示例 1:
输入: s = "abcdefg", k = 2
输出: "cdefgab"
示例 2:输入: s = "lrloseumgh", k = 6
输出: "umghlrlose"
限制:
1 <= k < s.length <= 10000
这个题目可以比较容易的想出一些解法,比如创建一个新的字符串,然后从第k个字符开始先拷贝到新字符串,然后再拷贝0~(k-1)字符。
char* reverseLeftWords(char* s, int n){
int len = strlen(s);
int i;
char *ret = (char *)malloc(sizeof(char) * len) + 1;
char *p = ret;
for(i = n; i < len; i++) {
*p++ = *(s+i);
}
for(i = 0; i < n; i++) {
*p++ = *s++;
}
*p = '\0';
return ret;
}
int main() {
char *str = "ABC123456789";
printf("str: %s\n", str);
printf("reverse: %s\n",reverseLeftWords(str, 3));
return 0;
}
这里的代码可以优化一下,上面遍历了2次,虽然2次遍历数量之和为N,但是可以利用字符串位置取模的方式在原字符串到尾部后再取n个首字符添加到新字符串尾部,简化到一个遍历中:
char* reverseLeftWords(char* s, int n){
int len = strlen(s);
int i;
char *ret = (char *)malloc(sizeof(char) * len) + 1;
char *p = ret;
for(i = n; i < n + len; i++) {
*p++ = *(s + i%len);
}
*p = '\0';
return ret;
}
小结:
字符串的反转,左旋,排序等等操作,需要特别注意,C语言中如果直接以char * str = "hello world"的方式定义的字符串,是不能去修改内容的,是一个常字符串,所以不能盲目的修改,一般对于这种操作,直接构建一个新字符串,然后再从原字符串中按规则取出字符填充到新字符串即可。