最小表示法详解
partychicken · · 题解
最小表示法是用于解决字符串最小表示问题的方法(废话
字符串的最小表示
循环同构
当字符串
则称
最小表示
字符串
simple的暴力
我们直接比较与
每次保留当前字典序最小的字符串与剩余的字符串比较。
int k=0,i=0,j=1;
for(;j<n;j++)
{
if(sec[(i+k)%n]==sec[(j+k)%n])
{
k++;
}
else
{
if(sec[(i+k)%n]>sec[(j+k)%n]%n)
{
i=j;
}
k=0;
}
}
随机数据下表现良好,但是可以构造特殊数据卡掉。
例如:对于
我们发现,当字符串中出现多个连续重复子串时,此算法效率降低,我们考虑优化这个过程。
最小表示法
算法核心
考虑对于一对字符串
不妨先考虑
所以我们比较时可以跳过下标
这样,我们就完成了对于上文暴力的优化。
时间复杂度
证明:显然
算法流程
- 初始化指针
i 为0 ,j 为1 ;初始化匹配长度k 为0 - 比较第
k 位的大小,根据比较结果跳转相应指针。若跳转后两个指针相同,则随意选一个加一以保证比较的两个字符串不同 - 重复上述过程,直到比较结束
- 答案为
i,j 中较小的一个
代码
int k=0,i=0,j=1;
while(k<n&&i<n&&j<n)
{
if(sec[(i+k)%n]==sec[(j+k)%n])
{
k++;
}
else
{
sec[(i+k)%n]>sec[(j+k)%n]?i=i+k+1:j=j+k+1;
if(i==j) i++;
k=0;
}
}
i=min(i,j);