重複的子字串 kmp解法

2021-10-09 16:42:14 字數 1862 閱讀 3731

題目描述:

給定乙個非空的字串,判斷它是否可以由它的乙個子串重複多次構成。給定的字串只含有小寫英文本母,並且長度不超過10000。

示例 1:

輸入: 「abab」

輸出: true

解釋: 可由子字串 「ab」 重複兩次構成。

示例 2:

輸入: 「aba」

輸出: false

示例 3:

輸入: 「abcabcabcabc」

輸出: true

解釋: 可由子字串 「abc」 重複四次構成。 (或者子字串 「abcabc」 重複兩次構成。)

解題思路

如果您的字串 s 包含乙個重複的子字串,那麼這意味著您可以多次 「移位和換行」`您的字串,並使其與原始字串匹配。

例如:abcabc

移位一次:cabcab

移位兩次:bcabca

移位三次:abcabc

現在字串和原字串匹配了,所以可以得出結論存在重複的子串。

基於這個思想,可以每次移動k個字元,直到匹配移動 length - 1 次。但是這樣對於重複字串很長的字串,效率會非常低。在 leetcode 中執行時間超時了。

為了避免這種無用的環繞,可以建立乙個新的字串 str,它等於原來的字串 s 再加上 s 自身,這樣其實就包含了所有移動的字串。

比如字串:s = acd,那麼 str = s + s = acdacd

acd 移動的可能:dac、cda。其實都包含在了 str 中了。就像乙個滑動視窗,一開始 acd (acd) ,移動一次 ac(dac)d,移動兩次 a(cda)cd。迴圈結束

所以可以直接判斷 str 中去除首尾元素之後,是否包含自身元素。如果包含。則表明存在重複子串。

**:簡化版:

class

solution

}

對於查詢子串是否存在問題可以套kmp

class

solution

else

}return next;

}static

intkmp

(string s,string p,

int[

] next)

else}if

(j >= p_len)

return i - j;

else

return-1

;}public

boolean

repeatedsubstringpattern

(string s)

}

kmp優化版本

next陣列可以得出當前字串的最大前字尾長度,如果s是迴圈字串,那麼next[len]一定是它最大迴圈字元子串的長度,總的字串長度一定是迴圈子串長度的倍數,此時只要我們只要判斷len能否被len - next[len]整除即可

class

solution

else

}return next;

}public

boolean

repeatedsubstringpattern

(string s)

}

變式:輸出字串的最小迴圈節

思路:基於以上思路,滿足條件的時候的輸出即可

class

solution

else

}return next;

}public

static

void

main

(string[

] args)}}

}

字串 KMP演算法,重複的子字串

普通的方法,雙指標逐個比較 class solution begin1 begin2 if match return false kmp方法,在乙個串中查詢是否出現過另乙個串,這是kmp的看家本領。如果len len next len 1 0 則說明 陣列長度 最長相等前字尾的長度 正好可以被 陣列...

重複的子字串

力扣上看到的一道題分享一下大佬的思想。給定乙個非空的字串,判斷它是否可以由它的乙個子串重複多次構成。給定的字串只含有小寫英文本母,並且長度不超過10000。示例 1 輸入 abab 輸出 true 解釋 可由子字串 ab 重複兩次構成。示例 2 輸入 aba 輸出 false 示例 3 輸入 abc...

重複的子字串

給定乙個非空的字串,判斷它是否可以由它的乙個子串重複多次構成。給定的字串只含有小寫英文本母,並且長度不超過10000。示例 1 輸入 abab 輸出 true 解釋 可由子字串 ab 重複兩次構成。示例 2 輸入 aba 輸出 false 示例 3 輸入 abcabcabcabc 輸出 true 解...