循环字符串的最小表示法的问题可以这样描述:对于一个字符串S,求S的循环的同构字符串S’中字典序最小的一个。
同构字符串举例:原字符串为abc,同构字符串为abc,bca,cab(类似于徐摆渡,摆渡徐,渡徐摆)
现要输出所有同构字符串中字典序最小/大的一个,以最小表示法为例:
设置双指针i=0, j=1。
如果s[i]>s[j], i=j++; 如果s[i]<s[j], j++;
如果s[i]=s[j], 设置指针k=0, 依次比较下面的字符大小。
例题:
#include <bits/stdc++.h> using namespace std; int len; string s; int getmin(string s){ int i=0,j=1,k=0,t; while(i<len&&j<len&&k<len){ t=s[(i+k)%len]-s[(j+k)%len]; if(!t)k++; else{ if(t>0) i+=k+1; else j+=k+1; if(i==j) j++; k=0; } } return min(i, j); } int main() { cin>>len>>s; int idx=getmin(s); for(int i=idx;i<len;++i) cout<<s[i]; for(int i=0;i<idx;++i) cout<<s[i]; //cout<<idx<<endl; cout<<endl; return 0; }