題目描述:
給定乙個非空的字串,判斷它是否可以由它的乙個子串重複多次構成。給定的字串只含有小寫英文本母,並且長度不超過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 解...