概念:
用于求一个字符串所有循环同构中字典序最小那个串的开头的位置。
何为循环同构?就是把字母一个个后移
AABC的同构有,
ABCA
BCAA
CAAB
具体方法:
两个指针i,j,表示当前字典序最小的开头。
初始i=0,j=1,我们对这两个串字符逐个比较直到不同,假设只相同了同k位
如果s[(i+k)%len] < s[(j+k)%len] ,那么我们确定i开头更小,同时j直接移到j+k+1位置,同样的i偏大就移动i
(这里的取余是为了(i+k),(j+k)超过长度范围之后比的是正确位置的字符)
j~j+k位置都不可能做开头(这应是唯一需要理解的地方啦)
代码:
int getmin(int len)
{
int i=0,j=1,k=0;
while (i<len && j<len && k<len){
int t = s[(i+k)%len] - s[(j+k)%len];
if (!t) k++;
else {
if (t<0) j += k+1;
else i += k+1;
if (i==j) j++;
k = 0;
}
}
return i<j?i:j;
}
int getmax(int len)
{
int i=0,j=1,k=0;
while (i<len && j<len && k<len){
int t = s[(i+k)%len] - s[(j+k)%len];
if (!t) k++;
else {
if (t>0) j += k+1;
else i += k+1;
if (i==j) j++;
k = 0;
}
}
return i<j?i:j;
}