最大最小表示法
之前学过,然后又忘了。老师说忘记算法是因为你当时学的时候没有认真的思考这个算法。感觉他说的挺对的。所以想写下我对这个算法的理解。
首先,这个算法并不难,但我是想不出这样的算法的。
字符串的最小(大)表示法的问题可以这样描述:
对于一个字符串S,求S的循环的同构字符串S’中字典序最小(大)的一个。
由于语言能力有限,还是用实际例子来解释比较容易:设S=bcad,且S’是S的循环同构的串。S’可以是bcad或者cadb,adbc,dbca。而且最小表示的S’是adbc。
对于字符串循环同构的最小表示法,其问题实质是求S串的一个位置,从这个位置开始循环输出S,得到的S’字典序最小
一种朴素的算法就是找两个指针来记录位置,拿字典序最小来说,令i = 0, j = 1;
如果s[i] > s[j] i++, j++;
如果s[i] < s[j] j++;
如果s[i] = s[j], 设指针k, k++,向下比较,直到s[i] != s[j]
如果 s[i + k] > s[j + k] i = j;
否则 j++;
但是这个会很浪费时间,比如说这个字符串:bbbbbbbbbba
这个时候i = j 就会跑出n^2的复杂度
怎么办呢
举这个栗子
这个时候我们让它调到 i + k + 1的位置, 因为k是已经跑过的了,i不会再去跑k跑过的部分,所以时间复杂度就降到了n。
下面贴一个模板题:
String Problem HDU - 3374
题目链接:https://cn.vjudge.net/contest/163024#problem/O
题目大意:求给定字符串的字典序最小的字符串的首位置,字典序最大的字符串的首位置,以及最小循环节。
input:
abcder
aaaaaa
ababab
output
1 1 6 1
1 6 1 6
1 3 2 3
代码:
还有一个疑问就是最后为什么要return i < j ? i : j;
感觉直接return i就可以,改了之后往上交代码,发现直接return i也能a,不知道是数据太水还是真的可以直接return i。
共同学习,写下你的评论
评论加载中...
作者其他优质文章