1. 程式人生 > >leetcode-028. Implement strStr()

leetcode-028. Implement strStr()

題目要求匹配給定字串和模式串,如果模式串存在於字串中,則返回所在索引,如果不存在,則返回-1;

關於給定字串和模式串的匹配問題,是資料結構的經典問題,也有其對應的解決演算法,即KMP演算法。然而資料結構中引出KMP演算法也是為了解決暴力求解時,兩個指標回溯問題,導致o(mn)的時間複雜度而提出的。

因此對於字串的匹配,我們首先想到的就是暴力求解法。(*/ω\*)

一、暴力求解

思路:

     * 逐個比較haystack[i]的每個字元和needle[0],如果對應的字元不      * 相等,則跳過。繼續比較haystack[i+1],如果對應的字元相等,則繼續比較haystack[i+1]和needle[1],一直比較到needle的      * 最後一個節點,如果needle[j]中的j等於needle的長度,說明找到了一個答案,直接返回i。      * 如果外層遍歷完還是沒找到,則返回-1。

java實現:

public int strStr(String haystack, String needle) {         if(needle.isEmpty()){             return 0;         }         int m=haystack.length();         int n=needle.length();         if(n>m)  return -1;         for (int i = 0; i <=m-n; i++) {             int j=0;             for (; j < n; j++) {                 if(haystack.charAt(i+j)!=needle.charAt(j)) break;                 }             if(j==n) return i;         }                  return -1;                     }

另外一種方法:

     * 1.當needle遍歷到末尾,且每個字元都和haystack子串字元相同時,代表找到匹配的串。      * 2.在needle遍歷過程中,當存在與haystack子串不同的字元時,需要重新獲取haystack的子串進行匹配判斷。      * 3.當haystack和needle恰好同時遍歷到末尾時,還未找到匹配的串,則不存在匹配的串。

public int strStr2(String haystack,String needle){         for (int i = 0; ; i++) {             for (int j = 0; ; j++) {                 //1.找到匹配的串                 if(j==needle.length())    return i;                 //3.當haystack和needle同時遍歷完,還未找到匹配的串                 if(i+j==haystack.length())    return -1;                 //2.遍歷過程中存在不相同的字元時,從haystack中重新擷取子串進行匹配                 if(needle.charAt(j)!=haystack.charAt(i+j)) break;                              }                      }                       }

python實現:

二、KMP演算法實現

和嚴蔚敏的資料結構的方法基本一致:重要的是求得模式串的next陣列

java實現:

class Solution {    public int strStr(String haystack,String needle){         if(needle.isEmpty()){             return 0;         }         int i=-1,j=-1;         int m=haystack.length();         int n=needle.length();         int[] next=nextval(needle);         while(i<m&&j<n){             if(j==-1||(haystack.charAt(i)==needle.charAt(j))){                 ++i;                 ++j;      //若相等,則繼續向後比較             }             else{                 j=next[j];//若不相等,則模式串向右移動             }                  }         if(j>n-1){             return i-j;   //匹配成功,返回索引         }         else return -1;    //遍歷成功,不存在,返回-1          }     public static int[] nextval(String sub){         int[] next=new int[sub.length()+1];         char[] T=sub.toCharArray();         int length=sub.length();                  int k=-1;         int j=0;         next[0]=-1;         while(j<length-1){             if(k==-1||T[j]==T[k]){                 k++;                 j++;                 if(T[j]!=T[k]){                     next[j]=k;                 }else{                     next[j]=next[k];                 }                              }else{                 k=next[k];             }         }         return next;              }