题目描述:实现一个函数,能匹配字符串,如果匹配成功返回第一次出现的
index
,失败返回-1
,如果匹配串长度为0
返回0.
题目链接:Leetcode 28. Implement strStr()
KMP算法,根据needle
求出next数组,然后利用next数组的信息进行匹配,移动模式串来匹配,每当失配就移动模式串,如果模式串回到了-1
也就是第一个位置,那么相应的主串也移动一位进行比较即可。
next数组就是某个字符串的最长公共前缀的一个信息。
KMP的next数组的思想运用在很多地方,例如leetcode 214题,在最前面添加最少的字符使其成为回文串。
代码如下
class Solution {
public int strStr(String haystack, String needle) {
if (needle.length() == 0){
return 0;
}
if (haystack==null || needle==null || haystack.length() == 0) {
return -1;
}
int ans = -1;
char[] s = haystack.toCharArray();
char[] m = needle.toCharArray();
int[] nexts = getNextArray(m);
int si = 0;
int mi = 0;
while (si < s.length && mi < m.length) {
if (s[si] == m[mi]) {
si++;
mi++;
} else {
if (nexts[mi] == -1){
si++;
} else {
mi = nexts[mi];
}
}
}
return mi == m.length ? si - mi : -1;
}
public int[] getNextArray(char[] ms) {
if (ms.length == 1) {
return new int[]{-1};
}
int[] next = new int[ms.length];
next[0] = -1;
next[1] = 0;
int pos = 2;
int cn = 0;
while (pos < next.length) {
if (ms[pos - 1] == ms[cn]) {
next[pos++] = ++cn;
} else if (cn > 0) {
cn = next[cn];
} else {
next[pos++] = 0;
}
}
return next;
}
}