先说一一下题目描述:例如 abcdefg 如果向右侧旋转3 变成 efgabcd 显然算法可以通过一个一个的右移来实现,时间复杂度是 K*N,N是字符串长度,K是移动的个数
我们的目的是要找到一个时间复杂度为N并且空间复杂度是1的算法
(有一处感觉怪怪,他为什么 K = K%N 后就说复杂度是 N^2了,雾水,我怎么觉得应该是 K%N * N)哈哈
思考 abcdefg 右移动3位 那么最后的格局是 efg一定跑前面去了 abcd efg 割开,最后的结果啊 efg abcd,如果翻转结果串为 dcba gfe 观察发现就是 abcd efg两个各自翻转的结果,所以算法总结为:
假设右旋转 K 则
1. a0,a1...an-k-1 翻转
2. an-k, .. an-1 翻转
3. a0....an-1翻转
他有个更好的解释
对于这个问题,咱们换一个角度,可以这么做:
将一个字符串分成两部分,X和Y两个部分,在字符串上定义反转的操作X^T,即把X的所有字符反转(如,X="abc",那么X^T="cba"),那么我们可以得到下面的结论:(X^TY^T)^T=YX。显然我们这就可以转化为字符串的反转的问题了。
自己写的程序如下:
#include <stdio.h>
#include <string.h>
void swap(char *pA,char *pB)
{
char tmp = *pA;
*pA = *pB;
*pB = tmp;
}
void reverse(char *pArray,int f,int t)
{
while(f<t)
{
swap(pArray+f++,pArray+t--);
}
}
int main()
{
char str[100];
int nShift,nLen;
while(scanf("%s%d",str,&nShift) != EOF)
{
nLen = strlen(str);
nShift = nShift % nLen;
reverse(str,0,nLen-nShift-1);
reverse(str,nLen-nShift,nLen - 1);
reverse(str,0,nLen-1);
printf("%s\n",str);
}
}