字符串的最小表示
一个字符串S通过循环移位能够得到一些别的字符串,比如“abcde”循环一次可以得到“bcdea”,循环两次得到“cdeab”,等等。这些串当中字典序最小的那个就叫做S的最小表示。
求出字符串的最小表示可以方便地判断两个串是否循环同构。
某些别的求解方法
求最小表示或者循环同构实际上有很多别的方法的。。。并且渐进时间复杂度达到理论下界的O(n)的做法也有很多。。
比如说直接求最小表示的话可以把字符串在后面接一遍然后搞一个后缀自动机每次顺着最小的边走n步就可以了呀~
但是常数巨大空间巨大。。。(逃
如果求循环同构的话把第一个串在后面接一遍然后第二个串跑KMP就可以了呀~
其实感觉这种做法的理论复杂度和常数都不比最小表示法啥的差。。
最小表示法
参考2003年集训队论文 周源《浅析“最小表示法”思想在字符串循环同构问题中的应用》
设一个字符串的函数M(S)返回的是从S的第M(S)个字符开始引起的S一个循环表示是S的最小表示。
当要判断两个长度为n的串S和T是否循环同构的时候,首先把S和T都在后面接一遍,然后设两个指针p1和p2分别指向S和T中的字符。当p1=M(S)并且p2=M(T)的时候,如果S和T是循环同构的,那么一定可以得到从p1和p2向后匹配n个位置都是相等的。
最小表示法求字符串循环同构的基本思路就是假设它们是循环同构的,然后去寻找可以成功向后匹配n个字符的位置,如果找不到就说说明它们不是循环同构的。接下来的讨论中假设S和T是循环同构的。
在找M(S)和M(T)的时候,因为我们是从前往后找的,那么只要我们能保证在这个时刻有 p1<M(S<