題目地址:https://leetcode-cn.com/problems/implement-strstr/java
給定一個 haystack 字符串和一個 needle 字符串,在 haystack 字符串中找出 needle 字符串出現的第一個位置 (從0開始)。若是不存在,則返回 -1。面試
示例 1:算法
輸入: haystack = "hello", needle = "ll"
輸出: 2函數
示例 2:指針
輸入: haystack = "aaaaa", needle = "bba"
輸出: -1code
說明:
當 needle 是空字符串時,咱們應當返回什麼值呢?這是一個在面試中很好的問題。對於本題而言,當 needle 是空字符串時咱們應當返回 0 。這與C語言的 strstr() 以及 Java的 indexOf() 定義相符。索引
本題就是要實現一個indexOf函數,首先想到的就是雙指針在兩個串中比較。leetcode
暴力解法(BF)就依次掃描若是有相同的同步繼續,出現不一樣就中斷了,模式串回到起點主串回到下個開頭點。也就是說主串的長度會遍歷完,剩下的看模式串掃到何時中斷。在最差的狀況下每次模式串遍歷到最後一箇中斷主串最末端才匹配到那就是O(n*m)字符串
邊界get
細節
public int strStr(String haystack, String needle) { char[] hay = haystack.toCharArray(); char[] need = needle.toCharArray(); int h = hay.length; int n = need.length; int i=0,j=0; while(j < h && i < n){ if(hay[j] == need[i]){ i++; j++; }else { j=j-i+1; i=0; } } if(i >= n) return j-i; else return -1; }
除了兩個指針依次比較以外,判斷一個串是否含另外一個串直接去依次截取目標長度的子串,判斷有無相等的子串。這裏截取我直接用的substring方法,這個也實現過不少次了,怎麼寫都同樣但咱們必定要知道它的實現是怎樣的才能客觀的分析它的複雜度,這裏它就是一次遍歷。所以下面代碼的解法也是一個兩層的遍歷
public int strStr(String haystack, String needle) { int n = needle.length(); int h = haystack.length(); for (int i = 0; i < h - n + 1; i++) { if (haystack.substring(i, i + n).equals(needle)) { return i; } } return -1; }
其實這種解法和解法一是如出一轍只不過前者把截取和比較直接寫了出來,它比解法一優的點只是少遍歷了後面短的部分一個是h * (?)另外一個是(h-n+1)* (?),是由於兩層遍歷分開寫能夠這樣作。外面遍歷子串的開頭,裏面再遍歷子串與模式串是否相等。而解法一放到了一個循環也作到了這個邏輯
字符串匹配算法算是一個比較經典的算法,也是在計算機領域實際應用超多的算法。上面不管是解一仍是解二其實都是全遍歷比較。許多科學家都發明瞭更多減小比較次數的方式,好比RK算法、BM算法以及KMP算法。這些在這裏暫時不介紹。以後在其餘系列會出單篇講解這類以及其餘的算法。