[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;
         }
     }
 };


發佈了83 篇原創文章 · 獲贊 32 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章