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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值