28. 实现 strStr()
这可以是一个暴力匹配的简单题。但如果这样写,就显得毫无意义。
于是,可以写KMP算法。
这题的重点是理解KMP算法中的next求解方式,按照之前我们所努力的,给我们的求解问题建模:
设要匹配的串是pattern,设k是pattern[j]匹配失败时该返回的一系列位置,我们保证k是从大到小的,也就是说pattern[j]匹配失败时候,会进行多次重新定位,这一系列的位置是k的取值空间,设集合是kset。
于是我们就可以得到,首先next[0]=-1:
- 按照我们的编程模型,k是pattern[j]匹配失败时该返回的一系列位置,于是必是已经求解出来的。
- 假设pattern[k]==pattern[j],显然next[j+1]=k+1,画图理解next的定义就能明显看出来。
- 假设pattern[k]!=pattern[j],我们的目的是为了求解next[j+1],于是需要找到一个满足步骤2的k值,因为k越大越好,所以取kset里面较小于当前k值的值,于是k=next[k],继续求解
于是就可以书写代码了:
public int[] getNext(String pattern) {
int[] next = new int[pattern.length()];
next[0] = -1;
int k = -1, j = 0;//k定义为当前j不匹配时候所在的一串位置中的一个,由大到小
while (j < pattern.length() - 1) {
if (k == -1 || pattern.charAt(k) == pattern.charAt(j)) {
next[++j] = ++k;
} else k = next[k];
}
return next;
}
public int strStr(String haystack, String needle) {
if (needle == null || needle.length() == 0) return 0;
int[] next = getNext(needle);
int i = 0, j = 0;
while (i<haystack.length()) {
if (j==-1||needle.charAt(j)==haystack.charAt(i)){
++j;++i;
}else j=next[j];
if (j==needle.length()) return i-needle.length();
}
return -1;
}