【学习笔记】最小表示法


一、最小表示法解决的问题:找到一个字符串的循环同构串中字典序最小的那个串。

二、字符串的循环同构:
比如长度为5字符串“abcde”,它的5个循环同构串有:
abcde,bcdea,cdeab,deabc,eabcd;其中字典序最小的串为“abcde”。

三、求“abcde”的字典序最小的循环同构串
1.把“abcde”再接一遍,变成“abcdeabcde”,令s[]=“abcdeabcde”,默认下标从1开始;
2.设置两个指针,一个指向下方第一个串的第一个字符(i=1),一个指向下方第二个串的第二个字符(j=2)。
这个指针是我们要找的字典序最小的串的起点。
abcdeabcde
abcdeabcde
如果从i开始(包括i)往后k个字符和从j开始(包括j)往后k个字符都相等,且s [i+k]>s[j+k],那么从i到i+k-1之间的任何一个字符为首字符时,它的字典序一定不是最优的,将i修改为i=i+j+1;

因为每个指针最多跳转n次,所以时间复杂度为O(n)

四、代码

    while(i<=6&&j<=6) //字符串长度为6 拼接后为12
    {
        for(k=0;k<6&&b[i+k]==b[j+k];k++);//公共前缀,找到第一个不相等的位置
        if(k==6) break;      
        if(b[i+k]>b[j+k])  
        {
            i+=k+1;       //修改指针
            if(i==j) i++; 
        }
        if(b[i+k]<b[j+k])
        {
            j+=k+1;
            if(i==j) j++;
        }
    }
    int st=min(i,j),ed;
    ed=st+6-1;
原文地址:https://www.cnblogs.com/zzyh/p/14785281.html