最小表示:给定一个字符串,如果我们不断把它的最后一个字符放到开头,最终会的到n个字符,称这n个字符串是循环同构的。这些字符串中最小的一个,称为字符串的最小表示法。
首先我们复制一份S放在它后面;
让i=0,j=1,k=0,其中i,j,k表示的是以i开头和以j开头的字符串的前k个字符相同,如果在i+k与j+k处发现不相等,假设SS[I+K]>SS[J+K],那么B[i]不是最小表示(B[j]更小),同样B[i+1],B[i+2]…B[i+k]都不是最小(B[j+1],B[j+2]…B[j+k]更小)所以可以直接跳过这些不可能的数,令i=i+k+1再与B[j]比较,要注意i与j不能相等,若i>n,B[j]为最小表示;若j>n,B[i]为最小表示,否则重复上一步。
代码:
int n=strlen(s+1);
for(int i=1;i<=n;i++)
s[n+i]=s[i];
int i=1,j=2,k=0;
while(i<=n&&j<=n)
{
for(k=0;k<=n&&s[i+k]==s[j+k];k++)
if(k==n)break;//s只由一个字符构成
if(s[i+k]>s[j+k])
{
i=i+k+1;
if(i==j)
i++;
}
else
{
j=j+k+1;
if(i==j)
j++;
}
ans=min(i,j);
}