Arrays 最长正确前缀/后缀算法为何/如何工作?
LPS(最长正确前缀,也是后缀)算法如下所示:Arrays 最长正确前缀/后缀算法为何/如何工作?,arrays,algorithm,prefix,suffix,knuth-morris-pratt,Arrays,Algorithm,Prefix,Suffix,Knuth Morris Pratt,LPS(最长正确前缀,也是后缀)算法如下所示: public static int[] constructLPSArray(String s) { int n = s.length(); int[] arr = new int[n]; int j = 0; for (int i = 1; i < n; ) { if (s.charAt(i) == s.charAt(j)) {
public static int[] constructLPSArray(String s) {
int n = s.length();
int[] arr = new int[n];
int j = 0;
for (int i = 1; i < n; ) {
if (s.charAt(i) == s.charAt(j)) {
arr[i] = j + 1;
i++;
j++;
} else {
if (j != 0) {
j = arr[j - 1];
} else {
i++;
}
}
}
return arr;
}
更具体地说,为什么
j=arr[j-1]
起作用?或者我们为什么要这么做?如何验证此步骤的正确性?假设我们正在解析一个字符数组,其中i
和j
的位置如下:
a b a b x x a b a b ...
^ ^
j i
在保持arr的情况下:
0 0 1 2 0 0 1 2 3 4
一,。e、 ,该长度的s的每个子字符串的最长前缀/后缀的长度,直到i
。您可能可以猜到,这是如何从算法的其余部分生成的。现在,如果i
之后的下一个字符与j
之后的下一个字符不匹配
a b a b x x a b a b a ...
^ ^
j i
我们不必重试匹配,因为我们知道前面前缀/后缀中最长的前缀/后缀!查找arr[j-1]
得到2–因此我们基本上缓存了此处突出显示的部分的信息
A B a b x x a b A B a ...
=== ^ === ^
j i
是相同的,不需要再次比较 *这里还有一个解决方案*
*Here's one more solution*
int length=str.length();
int mid=length/2;
if(length<2){
System.out.println("-1");
}
for(int i=mid;i>=0;i--){
String prefix=str.substring(0,i);
String suffix=str.substring(length-i,length);
if(suffix.equals("") || prefix.equals("")){
System.out.println("-1");
}
if(suffix.equals(prefix)){
System.out.println(suffix.length());
break;
}
}
int length=str.length();
int mid=长度/2;
如果(长度=0;i--){
字符串前缀=str.substring(0,i);
字符串后缀=str.substring(长度-i,长度);
if(后缀.equals(“”)|前缀.equals(“”){
系统输出打印项次(“-1”);
}
if(后缀等于(前缀)){
System.out.println(后缀.length());
打破
}
}
您能解释一下为什么时间复杂度是O(n)而不是n^2,其中n是字符串的长度吗?由于“j”可能在某些循环迭代中递减,它似乎可能是O(n^2)。它是否需要查找“我们以前的前缀/后缀中最长的前缀/后缀”,该前缀/后缀对任何i只递减j一次?想知道它的复杂度是线性的。@JoeBlack x=#i,j增加了;y=#j减小;z=#只有i增加;A=x+y+z=我们知道的算法的总运行时间x+z *Here's one more solution*
int length=str.length();
int mid=length/2;
if(length<2){
System.out.println("-1");
}
for(int i=mid;i>=0;i--){
String prefix=str.substring(0,i);
String suffix=str.substring(length-i,length);
if(suffix.equals("") || prefix.equals("")){
System.out.println("-1");
}
if(suffix.equals(prefix)){
System.out.println(suffix.length());
break;
}
}