最小表示法/最大表示法 O(n)
来源:互联网 发布:怎么用农村淘宝买东西 编辑:程序博客网 时间:2024/05/08 08:49
循环字符串的最小表示法的问题可以这样描述:
对于一个字符串S,求S的循环的同构字符串S’中字典序最小的一个。
由于语言能力有限,还是用实际例子来解释比较容易:
设S=bcad,且S’是S的循环同构的串。S’可以是bcad或者cadb,adbc,dbca。而且最小表示的S’是adbc。
对于字符串循环同构的最小表示法,其问题实质是求S串的一个位置,从这个位置开始循环输出S,得到的S’字典序最小。
一种朴素的方法是设计i,j两个指针。其中i指向最小表示的位置,j作为比较指针。
令i=0,j=1
如果S[i] > S[j] i=j, j=i+1
如果S[i] < S[j] j++
如果S[i]==S[j] 设指针k,分别从i和j位置向下比较,直到S[i] != S[j]
如果S[i+k] > S[j+k] i=j,j=i+1
否则j++
返回i
起初,我想在j指针后移的过程中加入一个优化。就是j每次不是加1,而是移动到l位置。其中,l>j且S[l]<=S[j]。但是,即使加入这一优化,在遇到bbb…bbbbbba这样的字符串时复杂度将退化到O(n^2)。
注意到,朴素算法的缺陷在于斜体的情况下i指针的移动太少了。针对这一问题改进就得到了最小表示法的算法。最小表示法的算法思路是维护两个指针i,j。
令i=0,j=1
如果S[i] > S[j] i=j, j=i+1
如果S[i] < S[j] j++
如果S[i]==S[j] 设指针k,分别从i和j位置向下比较,直到S[i] != S[j]
如果S[i+k] > S[j+k] i=i+k
否则j++
返回i和j的小者
注意到上面两个算法唯一的区别是粗体的一行。这一行就把复杂度降到O(n)了。
值得一提的是,与KMP类似,最小表示法处理的是一个字符串S的性质,而不是看论文时给人感觉的处理两个字符串。
应用最小表示法判断两个字符串同构,只要将两个串的最小表示求出来,然后从最小表示开始比较。剩下的工作就不用多说了。
- int MinimumRepresentation(char *s, int l)
- {
- int i = 0, j = 1, k = 0, t;
- while(i < l && j < l && k < l) {
- t = s[(i + k) >= l ? i + k - l : i + k] - s[(j + k) >= l ? j + k - l : j + k];
- if(!t) k++;
- else{
- if(t > 0) i = i + k + 1;
- else j = j + k + 1;
- if(i == j) ++ j;
- k = 0;
- }
- }
- return (i < j ? i : j);
- }
然后主函数 设置变量 = 所求的, 循环输出, 不断++, %=n就好了
代码:
int getMin(char *s){ int i = 0, j = 1, l; int len = strlen(s); while(i < len && j < len) { for(l = 0; l < len; l++) if(s[(i + l) % len] != s[(j + l) % len]) break; if(l >= len) break; if(s[(i + l) % len] > s[(j + l) % len]) { if(i + l + 1 > j) i = i + l + 1; else i = j + 1; } else if(j + l + 1 > i) j = j + l + 1; else j = i + 1; } return i < j ? i : j;}int getMax(char *s){ int len = strlen(s); 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) { if(j+k+1 > i) j = j+k+1; else j = i+1; } else if(i+k+1 > j) i = i+k+1; else i = j+1; k = 0; } } return i < j ? i : j;}
- 最小表示法/最大表示法 O(n)
- 字符串最小表示法 O(n)算法
- 字符串最小表示法 O(n)算法
- 字符串 最小表示法 O(n)算法
- 字符串最小表示法 O(n)算法
- 最小表示法 最大表示法
- 最大表示法与最小表示法
- 字符串 最小表示法 O(n)算法 【模板】
- 最小(最大)表示法模板
- HDU 3374 KMP 最大表示法 最小表示法
- 字符串的最小表示法和最大表示法
- 最小表示法和最大表示法详解
- 最小表示法和最大表示法模板
- hdu5442 最小最大表示法+kmp
- 字符串的最小/最大表示法
- hdu3374String Problem kmp+最大最小表示法
- 环形字符串最小最大表示法
- 字符串的最大最小表示法 模板
- Docker中配置简单的Nginx+Tomcat的web负载均衡
- 一步步封装Retrofit + RxJava2
- 第十二章 与Spring集成(二) JavaWeb应用
- troubleshooting之解决yarn-client模式导致的网卡流量激增问题
- HDU 2196 Computer (树型dp/树直径)
- 最小表示法/最大表示法 O(n)
- 乱写c++ serverno+timestamp+threadid生成制定长度字符串
- bash: /opt/hisi-linux/x86-arm/arm-hisiv300-linux/target/bin/arm-hisiv300-linux-gcc:no such file or..
- VLC和Qt结合编写流媒体rtsp播放器
- 简评骑士与凯尔特人交易对双方影响
- Java判断时间在5分钟的之内方法
- C实现椒盐噪声生成
- LeetCode编程练习
- python肘部法则 最优分类