参考文章:http://blog.csdn.net/u012501262/article/details/21823363
引子
首先有一个字符串s,我们可以对他进行操作,每次操作都可以将第一个字符移动到最后一个字符。我们要求解经过n次操作后,得到的字典序最小的字符串是什么。
一.朴素算法
朴素算法利用两个指针i,j。初始i = 0,j = 1。i 为最小的字符串的开头位置
a.当s[i] > s[j] 时
i = j;//因为j是更小的
j++;
b.当s[i] < s[j]时
j ++;
c.当s[i] == s[j] 时
k = 0
n = strlen(s)
while(k < n)
{
if(s[(i + k)% n] < s[(j + k) % n])
j ++;
if(s[(i + k) %n] > s[(j + k) %n])
i = j,j ++;
}
二.最小表示法的实现
就是在朴素的基础上进行一些更改
仍旧是设置两个指针i = 0,j = 1.但这两个指针都是可以作为指向最小位置的指针,而先到达n的不是最小位置。如果k到达n,意味着整个字符串都相等,那么最小位置就是0
从k = 0 开始,如果s[(i + k) %n] == s[(j + k) %n],就一直k ++
if(s[(i + k) %n] > s[(j + k) %n])
i = i + k + 1(也就是从i 到 i + k都不可能是最小的位置)
设i'属于[i,i+k]
有s[i',i + k - 1] == s[i' + j - i,j + k - 1]而s[i + k] > s[j + k]
另一面同理。记得k清零
如果i == j,j++。错开
代码如下:
int minandmax(int x)
{
int i = 0,j = 1,k = 0;
int t;
while(i < n && j < n && k < n)
{
t = s[(i + k) % n] - s[(j + k) %n];
if(t == 0)
{
k ++;
}
else
{
if(t > 0)
{
i = i + k + 1;
}
else
{
j = j + k + 1;
}
}
if(i == j)
{
j ++;
}
k = 0;
}
}
return min(i,j);
}