最小表示法

概念:

用于求一个字符串所有循环同构中字典序最小那个串的开头的位置。

何为循环同构?就是把字母一个个后移

AABC的同构有,

ABCA

BCAA

CAAB

具体方法:

两个指针i,j,表示当前字典序最小的开头。

初始i=0,j=1,我们对这两个串字符逐个比较直到不同,假设只相同了同k位

如果s[(i+k)%len]  < s[(j+k)%len]  ,那么我们确定i开头更小,同时j直接移到j+k+1位置,同样的i偏大就移动i

(这里的取余是为了(i+k),(j+k)超过长度范围之后比的是正确位置的字符)

j~j+k位置都不可能做开头(这应是唯一需要理解的地方啦)

代码:

int getmin(int len)
{
    int i=0,j=1,k=0;
    while (i<len && j<len && k<len){
        int t = s[(i+k)%len] - s[(j+k)%len];
        if (!t) k++;
        else {
            if (t<0) j += k+1;
            else i += k+1;
            if (i==j) j++;
            k = 0;
        }
    }
    return i<j?i:j;
}

int getmax(int len)
{
    int i=0,j=1,k=0;
    while (i<len && j<len && k<len){
        int t = s[(i+k)%len] - s[(j+k)%len];
        if (!t) k++;
        else {
            if (t>0) j += k+1;
            else i += k+1;
            if (i==j) j++;
            k = 0;
        }
    }
    return i<j?i:j;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值