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