最小(大)表示法

模板题:POJ 1509 传送门


给你一个字符串,该字符串首尾相连,让你找到一个位置,使得该字符串从这个位置展开字符串字典序最小(大)。
例如一个字符串bacfea,该字符串从第六个位置展开,可以得到abacfe,字典序是最小的。
思路:首先设定x=k=0,y=1;x,y表示两个起点,k表示x和y开始连续的k个字符相同。这时候我们一直往后比较str[x+k]和str[y+k],有三种情况:

  1. str[x+k]==str[y+k] 则 k++。
  2. str[x+k]>str[y+k] 则 x+=k+1。
  3. str[x+k]<str[y+k] 则 y+=k+1。

第一种情况不解释了, 第二种情况为什么不是x++而是x+=k+1呢?因为我们上一步已经知道str[x]~ str[x+k-1]==str[y]~ str[y+k-1],但是现在有str[x+k]>str[y+k],所以我们在 str[x]~ str[x+k]中不可能找到比str[x+k+1]更好的起点。由于k+1的不确定性,第二种和第三种情况最后都需要判断x是不是等于y,如果是的话必须要让其中一者++。另外,因为不符合条件的一者总是会更新到另一者后面,我们只需输出min(x,y)即可。

这些东西用文字解释起来总是很乱,看代码吧,模拟一下应该不难理解:

int MIN_MAX_PRESS(string temp)
{
    temp = temp + temp;
    int len = temp.size();
    int x, y, k;
    x = k = 0;
    y = 1;
    while (x + k < len && y + k <  len)
    {
        if (temp[x + k] == temp[y + k])
            k++;
        else if (temp[x + k] > temp[y + k])
        {
            x += k + 1;
            k = 0;
        }
        else
        {
            y += k + 1;
            k = 0;
        }
        if (x == y)
            x++;
    }
    return min(x + 1, y + 1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hesorchen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值