目录
最小表示法
题意 :
给你一个字符串 a
, 找出字符串 a
的的循环同构串中字典序最小的一个
循环同构串 :
把字符串 a
从任意一个地方切开,将两部分交换位置,重新首尾相连形成的串
算法 :
定义指针 i
, j
, 匹配长度 k
初始 i=0,j=1,k=0
比较 a[i+k]
和 a[j+k]
若
a[i+k]=a[j+k]
则k++
若
a[i+k]>a[j+k]
则i=i+k+1
若
a[i+k]<a[j+k]
则j=j+k+1
若上述操作完之后
i=j
则i++
以
min(i,j)
为起点长度为len
的串即为所求
时间复杂度:
因为 i,j,k
最多跳 n
次,所以时间复杂度 /(O(n)/)
code:
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+5;
int n,a[N];
inline int min_show(){
int i=0,j=1,k=0;
while(i<n&&j<n&&k<n){
if(a[(i+k)%n]==a[(j+k)%n])
++k;
else{
if(a[(i+k)%n]>a[(j+k)%n]) i=i+k+1;
else j=j+k+1;
if(i==j) ++i;
k=0;
}
}
return min(i,j);
}
signed main(){
cin>>n;
for(int i=0;i<n;++i)
cin>>a[i];
int s=min_show();
for(int i=0;i<n;++i)
cout<<a[(i+s)%n]<<" ";
}
原创文章,作者:carmelaweatherly,如若转载,请注明出处:https://blog.ytso.com/270988.html