给定字符串,这个字符串是循环的,要求寻找一个位置,以该位置为起点的字符串的字典序在所有的字符串中中最小。
暴力算法:
O(n)的时间枚举起始位置,O(n)的时间比对字符串的字典序,总的时间复杂度是O(n^2)。
线性算法:
开始,i=0,j=1,k=0,其中i,j,k代表以i开头和以j开头的字符串的前k个字符相同
只有三种情况
1.如果str[i+k]==str[j+k] k++。
2.如果str[i+k] > str[j+k] i = i + k + 1,即最小表示不可能以str[i->i+k]开头。
3.如果str[i+k] < str[j+k] j = j + k + 1,即最小表示不可能以str[j->j+k]开头。
那么只要循环n次,就能够判断出字符串的最小表示是以哪个字符开头。
最小表示法代码:
int minRepresent()
{
int n = strlen(str);
int i = 0,j = 1, k = 0;
while(i<n && j<n && k<n)
{
int t = str[(i+k)%n] - str[(j+k)%n] ;
if(t == 0)
k++;
else
{
if(t>0)
i+=k+1;
else
j+=k+1;
if(i==j)
j++;
k = 0;
}
}
return i < j ? i : j;
}
同理
最大表示法代码:
int maxRepresent()
{
int n = strlen(str);
int i = 0, j = 1, k = 0;
while(i<n && j<n && k<n)
{
int t=str[(i+k)%n]-str[(j+k)%n];
if(t==0)
k++;
else
{
if(t > 0)
j+=k+1;
else
i+=k+1;
if(i==j) j++;
k=0;
}
}
return i < j ? i : j;
}