1. 程式人生 > 其它 >力扣28題、459題(KMP演算法)

力扣28題、459題(KMP演算法)

28.strStr()

基本思想:

KMP演算法

具體實現:

要在文字串:aabaabaafa 中查詢是否出現過一個模式串:aabaaf。

A 計算字首表,得到next陣列

本題用-1的方式實現

字首表是下標i之前(包括i)的字串,有多大長度的相同字首字尾

next[i]表示i(包括i)之前最長相等的前後綴長度 - 1(其實就是j)

B 使用next陣列來做匹配

程式碼:

class Solution {
    public void getNext(int[] next, String s){
        int j = -1;
        next[0] = j;
        
for (int i = 1; i < s.length(); i++){ while ( j >= 0 && s.charAt(i) != s.charAt(j + 1)){ j = next[j]; } if (s.charAt(i) == s.charAt(j + 1)){ j++; } next[i] = j; } } public int strStr(String haystack, String needle) {
if (needle.length() == 0){ return 0; } int[] next = new int[needle.length()]; getNext(next, needle); int j = -1; for (int i = 0; i < haystack.length(); i++){ while (j >= 0 && haystack.charAt(i) != needle.charAt(j + 1)){ j
= next[j]; } if (haystack.charAt(i) == needle.charAt(j + 1)){ j++; } if(j == needle.length() - 1){ return (i - needle.length() + 1); } } return -1; } }

459、重複的子字串

具體實現:

A 計算字首表,得到next陣列

本題用-1的方式實現

B 使用next陣列來做匹配

最長相等前後綴的長度為:next[len - 1] + 1

陣列長度為len

如果len % (len - (next[len - 1] + 1)) == 0 ,

則說明 (陣列長度-最長相等前後綴的長度) 正好可以被 陣列的長度整除,說明有該字串有重複的子字串。

(陣列長度-最長相等前後綴的長度) 相當於第一個週期的長度,也就是一個週期的長度

如果這個週期可以被整除,就說明整個陣列就是這個週期的迴圈

程式碼:

class Solution {
    public void getNext(int[] next, String s){
        int j = -1;
        next[0] = j;
        for (int i = 1; i < s.length(); i++){
            while ( j >= 0 && s.charAt(i) != s.charAt(j + 1)){
                j = next[j];
            }
            if (s.charAt(i) == s.charAt(j + 1)){
                j++;
            }
            next[i] = j;
        }
    }
    public boolean repeatedSubstringPattern(String s) {
        if (s.length() == 0){
            return false;
        }

        int[] next = new int[s.length()];
        getNext(next, s);
        int len = s.length();
        if (next[len - 1] != -1 && len % (len - (next[len - 1] + 1)) == 0) {
            return true;
        }
        return false;
    }
}