[leetcoide] 【字符串】28. Implement strStr()

Implement strStr().

Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.


题意

两个字符串 haystack和needle ,如果needle是haystack的子串,返回needle在haystack中出现的索引,如果needle不是haystack的子串,返回-1;

题解

可以暴力破解,就是逐一比较。这样的时间复杂度是O(M*N)
最好的方法是kmp算法,我这里推荐一篇非常简单明了的文章,我也是看这篇文章搞懂了kmp  

难点就是建立公共前后缀数组(next数组),
原理就是这样,但是代码实现过程也比较难理解,这里也简单介绍一下代码实现过程:
getNext中,next[i]为前i个字符里公共前后缀的个数减1 (表示字符索引)。i从0到 needle.length() - 1遍历,j为此时公共前后缀的个数减1(表示字符索引),
先说needle[i]==needle[j]的情况,此时索引0-j的字符与i-j到i-1的字符是相等的,判断第i个和第j+1个是否相等,相等则j+1

其次是needle[i]!=needle[j]的情况,这个情况比较难理解

图中黄色部分是相等的,因此

图中红色部分也是相等的。这样0-next[j]与i-next[j]到i也是相等的,这样循环找到最大公共前后缀,直到needle[j]==needle[i]或者next[j]=-1。

这样,就可以做出needle的next数组了。
最后就是needle和haystack匹配,匹配方法相同。

class Solution {
 public:
     
     int strStr(string haystack, string needle) {
         if (haystack.empty()) return needle.empty() ? 0 : -1;
         if (needle.empty()) return 0;
         vector<int> next(needle.length() + 1);
         getNext(next, needle);
         int i = 0, j =-1;
         for (i=0;i< haystack.length();i++) 
         {
             while (j != -1 && haystack[i] != needle[j+1]) 
                j = next[j];
            if(haystack[i]==needle[j+1])
                j++;
            if(j==needle.length()-1)
                return i-j;
             
         }
         return -1;
     }
     void getNext(vector<int> &next, string &needle) {
         int i = 0, j = -1;
         next[i] = j;
         for(i=1;i!=needle.length();i++) 
         {
             while (j != -1 && needle[i] != needle[j+1]) 
                j = next[j];
             if (needle[i] == needle[j+1]) j++; 
             next[i] = j;
         }
     }
 };


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值