求最长公共前缀和后缀—基于KMP的next数组
KMP算法最主要的就是计算next[]算法,但是我们知道next[]求的是当前字符串之前的子字符串的最大前后缀数,但是有的时候我们需要比较字符串中前后缀最大数,比如
LeetCode的shortest Palindrome 就是基于KMP算法求最短子字符串。
public static int[] longestPS(String s) { int sLen = s.length(); char[] p = s.toCharArray(); //存放最大前缀后缀数 int[] lNext = new int[sLen]; //最大前后缀数(前缀指针) int k = 0; //后缀指针 int j = 1; while(j < sLen) { if(p[k] == p[j]) { //相等则将前一次比较的结果加上这次:k+1;然后继续加1比较。 lNext[j] = k + 1; k++; j++; } else { //如果p[k] != p[j]则k是不是在初始位置,是的话,K不变,后缀指针加1; if(k == 0) { j++; } else { //k不为0,说明指针不在初始位置。根据lNext数组,找到上一个最大前后缀数的位置,继续判断。 k = lNext[k-1]; } } } return lNext; } /* * 举例:字符串 ABDABCE * 对应的lNext == {0,0,0,1,2,0,0}; * */
下面是KMP的next数组代码,用以比较。
public void GetNext(char* p,int next[]) { int pLen = strlen(p); next[0] = -1; int k = -1; int j = 0; while (j < pLen - 1) { if (k == -1 || p[j] == p[k]) { ++k; ++j; next[j] = k; } else { k = next[k]; } } }
如果想要更详细的学习KMP算法,建议请移步此篇博客,从头到尾彻底理解KMP,这是我学习中收收获最多的。