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]);
}
}
记录模板,直接用好了