LeetCode 28 找出字符串中第一个匹配项的下标
这里使用了KMP算法的相关知识,KMP算法中最重要的是对于Next数组的使用
对于KMP算法来说,我们在对于两个字符串进行比较时,如果我们发现当前字符不匹配,那么我们可以通过寻找到当前字符串位置为止的字符串的最长相等的前缀和后缀。
而Next数组就是为了保存这些位置的最长相等的前缀和后缀的位置。当我们在i位置发现字符串不匹配时,我们可以直接返回next[i-1]的值,从而从next[i-1]位置继续开始进行匹配
class Solution {
public int strStr(String haystack, String needle) {
int n = needle.length();
int []next = new int [n];
getNext(next,needle);
int j =0;
for(int i=0;i<haystack.length();i++){
while(j>0 && haystack.charAt(i)!=needle.charAt(j)){
j = next[j-1];
}
if(haystack.charAt(i)==needle.charAt(j)){
j++;
}
if(j==n){
return i - needle.length() + 1;
}
}
return -1;
}
public void getNext(int[] next,String s){
int j=0;
next[0]=0;
int n = s.length();
for(int i=1;i<n;i++){
while(j>0 && s.charAt(i)!=s.charAt(j)){
j = next[j-1];
}
if(s.charAt(i)==s.charAt(j)){
j++;
}
next[i] = j;
}
}
}
LeetCode 459 重复的字符串
这题也用到了KMP的相关思想。我们在求了next数组之后,我们可以得到最长相同的前缀和后缀,数组长度减去最长相同前后缀的长度相当于是第一个周期的长度,也就是一个周期的长度,如果这个周期可以被整除,就说明整个数组就是这个周期的循环。
class Solution {
public boolean repeatedSubstringPattern(String s) {
if(s.equals("")){
return false;
}
int n = s.length();
int []next = new int [s.length()];
getNext(next,s);
if(next[n-1]>0 && n%(n-next[n-1])==0){
return true;
}
return false;
}
public void getNext(int []next,String s){
int j=0;
next[0] =0;
for(int i=1;i<s.length();i++){
while(j>0 && s.charAt(i)!=s.charAt(j)){
j = next[j-1];
}
if(s.charAt(i)==s.charAt(j)){
j++;
}
next[i] = j;
}
}
}