BF暴力与KMP
例题:实现strStr()
- 题目:给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
- 思路:
1.BF暴力匹配
2.KMP算法
1.BF暴力
- 很容易想到的方法,即原串(i)与匹配串(j)逐一匹配,不匹配是,i回溯到i+1,j回溯到0重新匹配,复杂度较高
- 代码
1>.求两个字符串长度;
2>.匹配,a从i开始,b都从0开始;
3>.判断,匹配长度等于匹配串长度返回i,否则返回-1
class Solution {
public int strStr(String ss, String pp) {
int n = ss.length(), m = pp.length();
char[] s = ss.toCharArray(), p = pp.toCharArray();
// 枚举原串的「发起点」
for (int i = 0; i <= n - m; i++) {
// 从原串的「发起点」和匹配串的「首位」开始,尝试匹配
int a = i, b = 0;
while (b < m && s[a] == p[b]) {
a++;
b++;
}
// 如果能够完全匹配,返回原串的「发起点」下标
if (b == m) return i;
}
return -1;
}
}
2.KMP
- KMP之所以能减少算法的复杂度主要有两点:
1.KMP的原串指针不会进行回溯
【利用next数组可以匹配到符合条件的前缀,同时可以过滤掉一些不可呢的方案】
2.利用next数组使匹配串的指针不用回到起始点
- next数组的构建
- 代码
1>.初始化next数组,判断匹配串长度如果为0,直接返回0;
2>.构建next数组:
1.通过while循环,确定j的最后位置(0或匹配时的位置);
【如果不匹配j指针会一直向后退,直到相匹配或j0是结束循环】
【结束循环只有两个情况:1.匹配2.j0】
2.匹配时,j++相当于next[i]=j+1;
3.j=0,next[i]=j相当于next[i]=0;
3>.原串与匹配串进行匹配(借用next数组)
1.while循环,确认当遇到字符串不匹配时的情况(即匹配串中j指针的位置)
【一直不匹配一直循环,j0还不匹配时,自动i++,不用考虑】
2.匹配时,j++;
3.jm时,完全匹配,返回结果;
4>.没有找到匹配字符串时,返回-1;
class Solution {
public int strStr(String haystack, String needle) {
int n = haystack.length();
int m = needle.length();
if(m == 0){
return 0;
}
int[] next = new int[m];
for(int i = 1,j = 0;i<m;i++){
while(j>0 && needle.charAt(i)!=needle.charAt(j)){
j = next[j-1];
}
if(needle.charAt(i) == needle.charAt(j)){
j++;
}
next[i] = j;
}
for(int i = 0,j = 0;i<n;i++){
while(j>0 && haystack.charAt(i)!=needle.charAt(j)){
j = next[j-1];
}
if(haystack.charAt(i) == needle.charAt(j)){
j++;
}
if(j == m){
return i-m+1;
}
}
return -1;
}
}
复杂度
O(m+n)
声明
- 原作者:E.L.E
- <本文章著作权归作者所有,商业转载请获得作者授权,非商业转载请注明出处>
- <欢迎大家评论>