LeetCode 28.实现strStr()KMP算法
Posted 龚喜发财+1
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 28.实现strStr()KMP算法相关的知识,希望对你有一定的参考价值。
**题目:**实现 strStr() 函数。
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。
相关内容
(1)charAt() 方法可返回String指定位置的字符stringObject.charAt(index)
(2)字符串单模匹配
1. 暴力解法
2. KMP算法
思想:消除了主串指针的回溯,从而使算法效率有了某种程度的提高。整个KMP的重点就在于当某一个字符与主串不匹配时,我们应该知道j指针要移动到哪?
提取加速匹配的信息:
将指针j移到第二位
可以看出如果不匹配,j要移动的下个位置k,存在这样的性质,也就是说p[0,k-1]=p[j-k,j-1]
因为在P的每一个位置都可能发生不匹配,也就是说我们要计算每一个位置j对应的k,所以用一个数组next来保存,next[j] = k,表示当T[i] != P[j]时,j指针的下一个位置。
void Getnext(int next[],String p)
{
int j=0,k=-1;
next[0]=-1;
while(j<p.length-1)
{
if(k == -1 || p[j] == p[k])
{
j++;k++;
next[j] = k;
}
else k = next[k];
}
}
从头到尾现在还是不明白,等我再看看吧!!!
int KMP(String s,String t)
{
int next[MaxSize],i=0;j=0;
Getnext(t,next);
while(i<s.length&&j<t.length)
{
if(j==-1 || s[i]==t[j])
{
i++;
j++;
}
else j=next[j]; //j回退。。。
}
if(j>=t.length)
return (i-t.length); //匹配成功,返回子串的位置
else
return (-1); //没找到
}
解法一:暴力解法
我们可以让字符串 needle 与字符串 haystack 的所有长度为 m 的子串均匹配一次。为了减少不必要的匹配,我们每次匹配失败即立刻停止当前子串的匹配,对下一个子串继续匹配。如果当前子串匹配成功,我们返回当前子串的开始位置即可。如果所有子串都匹配失败,则返回 −1。
我的暴力解法:(辣鸡)
class Solution {
public int strStr(String haystack, String needle) {
if(needle.length()==0)
return 0;
if(haystack.length()==0&&needle.length()!=0)
return -1;
if(haystack.length()<needle.length())
return -1;
int i,j=0;
for(i=0;i<haystack.length();i++){
char c=haystack.charAt(i);
char c2=needle.charAt(j);
if(c==c2){
j++;
}
else{
i=i-j;
j=0;
}
if(j==needle.length())
return i-needle.length()+1;
}
return -1;
//if(i==haystack.length()&&j<needle.length())
//return -1;
//else
//return i-needle.length()+1;
}
}
解法二:KMP算法
class Solution {
public int strStr(String haystack, String needle) {
if(needle.equals("")) return 0;
int n1=haystack.length(),n2=needle.length();
int[]next=new int[n2];
getNext(next,needle);//计算子串中回退的位置
int i=0,j=0;
while(i<n1&&j<n2){
if(j==-1||haystack.charAt(i)==needle.charAt(j)){
i++;
j++;
}
else {
j=next[j];//j回退
}
if(j==n2) return i-n2;
}
return -1;
}
public void getNext(int [] next, String t){
//找到每个字符的前一个匹配位置
int j=0,k=-1;
next[0]=-1;
while(j<t.length()-1){
if(k==-1||t.charAt(j)==t.charAt(k)){
k++;
j++;
next[j]=k;//如果匹配则前一个匹配位置为k,否则说明k在开头,则next[j]=0
}
else{
k=next[k];//k调到上一个位置重新匹配
}
}
}
}
参考:KMP算法:https://www.cnblogs.com/yjiyjige/p/3263858.html
以上是关于LeetCode 28.实现strStr()KMP算法的主要内容,如果未能解决你的问题,请参考以下文章
leetcode 28. 实现 strStr()----KMP算法,朴素模式匹配算法----超万字长文详解