循环字符串的最小表示法的问题可以这样描述:对于一个字符串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, 依次比较下面的字符大小。

例题:

算法 循环字符串最小/大表示法(On)

 

#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;
}

 

相关文章: