后缀数组模板

class Solution {
    public String lastSubstring(String s) {
        int n=s.length();//s的长度
        int[] x=s.chars().map(a->a-'a').toArray();//rak数组,用于离散化记录数组中间状态的排序,初始值即s,最终值即Suffix[i]在所有后缀中的排名,且排名各不相同
        int[] ws=new int[Math.max(n,26)];//基数排序的桶,长度为最后全排序后的n或26个字母的大者
        int[] sa=IntStream.range(0,n).toArray();//排名为i的Suffix序号
        int[] y=new int[n];//中间数组,用于储存第二关键字的排序
        int p=26;//ws的使用上限,初始值为26个字母
        int q=0;
        for(int z=-1;;z++){
            int k=(int)Math.pow(2,z);//排序子数组长度
            q=0;
            Arrays.fill(ws,0);//初始化桶
            for(int a=n-k;a<n;a++)
                y[q++]=a;//第二关键字超出n部分,放在y数组开头
            for(int a=0;a<n;a++)
                if(sa[a]>=k)//注意第二关键字大于等于k
                    y[q++]=sa[a]-k;
            for(int a=0;a<n;a++)
                ws[x[a]]++;//基数排序步骤一
            for(int a=1;a<p;a++)
                ws[a]+=ws[a-1];//基数排序步骤二
            for(int a=n-1;a>=0;a--)
                sa[--ws[x[y[a]]]]=y[a];//基数排序核心步骤
            q=0;
            for(int a=0;a<n-1;a++)
                y[sa[a]]=x[sa[a]]==x[sa[a+1]]&&(sa[a]+k<n?x[sa[a]+k]:-1)==(sa[a+1]+k<n?x[sa[a+1]+k]:-1)?q:q++;//离散化数组
            y[sa[n-1]]=q;
            System.arraycopy(y,0,x,0,n);//放入rak数组
            p=q+1;//记录排序数量
            if(p==n)//如果n个数字已排序,排序结束
                break;
        }
        return s.substring(sa[n-1]);
    }
}

记录模板,直接用好了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值