[题目描述]:给定一个字符串,要求将字符串前面的若干个字符移动到字符串的尾部。
[Sample Input] abcdef 3
[Sample Output] defabc
基本解法:根据题意我们知道移动的过程如下:
abcdef->bcdefa->cdefab->defabc
这样一步步的移动,就会得到结果。
代码如下:
#include<stdio.h>
#include<string.h>
void leftShiftOne(char *s, int n);
void leftRotateString(char *s, int n, int m);
int main()
{
char buf[] = "abcdef";
int n = 3;
int len = strlen(buf);
leftRotateString(buf, len, n);
printf("%s\n", buf);
return 0;
}
void leftShiftOne(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 leftRotateString(char *s, int n , int m)
{
m = m % n;
while(m --)
leftShiftOne(s, n);
}
时间复杂度:m*O(n),空间复杂度: O(1)
高效解法:三步反转法(PS: 2011年还是2012年,408的数据结构算法题考查的知识点就是这个,剑指offer上也有相应的题)
移动的步骤:
1. 因为是移动3步,所以首先将abcdef分为 abc 和 def 这两部分
2. 由第1步得到的结果,分别进行reverse,得到 cba 和 fed
3. 将第2步得到的结果,进行拼接,得到cbafed。 整体进行一次reverse,得到defabc。
代码如下:
#include<stdio.h>
#include<string.h>
void leftRotateString(char *s, int n, int m);
void reverseString(char *s, int start, int end);
int main()
{
char buf[] = "abcdef";
int n = 3;
int len = strlen(buf);
leftRotateString(buf, len, n);
printf("%s\n", buf);
return 0;
}
void reverseString(char *s, int start, int end)
{
while(start < end)
{
char tmp = s[start];
s[start ++] = s[end];
s[end --] = tmp;
}
}
void leftRotateString(char *s, int n , int m)
{
m = m % n;
reverseString(s, 0, m - 1);
reverseString(s, m, n - 1);
reverseString(s, 0, n - 1);
}
时间复杂度:3*O(n),空间复杂度:O(1)