luooj1559最强阵容加强版

本文介绍了一种算法,用于寻找字符串中字典序最小的同构子串的起始位置。通过双指针和匹配长度的概念,有效地解决了这一问题,并提供了完整的C++实现代码。

题目链接
分析
用最小表示法返回最小表示串(字典序最小的同构串)第一个字符在原始串中的下标。
用两个指针i,j,i初始化为0,j初始化为1,用k表示当前已经匹配串的长度。如果str[i+k]==str[j+k],j++,否则如果str[i+k]>str[j+k],说明以i开始的同构串肯定不是最小的,并且以i开始的到以i+k开始的都不会是最小的,因为若以i+x开头,0<=x<=k,那么这时以j+x开头的串比这个串小,因为前面相等,比较到i+k和j+k发现str[j+k]小,因此就把i移到i+k+1。同理如果str[i+k]>str[j+k],把j移到j+k+1,如果i==j,j++。直到i,j,k中有一个大于等于串的长度为止。最后返回i和j里较小的那个,注意破链成环的问题,代码并没有处理。
代码

#include<bits/stdc++.h>
using namespace std;
char a[300005];
int slove(char *s, int l){  
    int i=0,j=1,k=0,x,y;  
    while(i<l&&j<l&&k<l){  
        if((i+k)>=l) x=i+k-l; else x=i+k;
        if((j+k)>=l) y=j+k-l; else y=j+k;
        if(s[x]==s[y]) k++;  
        else{  
            if(s[x]>s[y]) i=i+k+1;else j=j+k+1;  
            if(i==j) j++;
            k=0;  
        }  
    }  
  return (i<j?i:j);  
}
int main(){
  int n;
  scanf("%d",&n);
  for(int i=0;i<n;i++){
        getchar();
        char c;
        scanf("%c",&c);
        a[i]=c;
    }
  cout<<slove(a,n)+1<<endl;
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值