459. 重复的子字符串
给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。
示例 1:
输入: "abab"
输出: True
解释: 可由子字符串 "ab" 重复两次构成。
示例 2:
输入: "aba"
输出: False
示例 3:
输入: "abcabcabcabc"
输出: True
解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/repeated-substring-pattern
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
1.枚举
class Solution: def repeatedSubstringPattern(self, s: str) -> bool: n = len(s) for i in range(1, n // 2 + 1): if n % i == 0: if all(s[j] == s[j - i] for j in range(i, n)): return True return False
Python all() 函数
2、字符串匹配
class Solution: def repeatedSubstringPattern(self, s: str) -> bool: return (s + s).find(s, 1) != len(s)
3、KMP字符串快速匹配算法,算法复杂度O(m+n);
先计算next数组然后利用next数组
class Solution { public: bool kmp(const string& query, const string& pattern) { int n = query.size(); int m = pattern.size(); vector<int> fail(m, -1); //计算next数组 for (int i = 1; i < m; ++i) { int j = fail[i - 1]; while (j != -1 && pattern[j + 1] != pattern[i]) { j = fail[j]; } if (pattern[j + 1] == pattern[i]) { fail[i] = j + 1; } } //根据next数组实现跳转 int match = -1; for (int i = 1; i < n - 1; ++i) {//因为是这个题目,所以需要从1开始,普通的匹配从0开始 while (match != -1 && pattern[match + 1] != query[i]) { match = fail[match]; } if (pattern[match + 1] == query[i]) { ++match; if (match == m - 1) { return true; } } } return false; } bool repeatedSubstringPattern(string s) { return kmp(s + s, s); } };
4、优化的KMP
class Solution: def repeatedSubstringPattern(self, s: str) -> bool: def kmp(pattern: str) -> bool: n = len(pattern) fail = [-1] * n for i in range(1, n): j = fail[i - 1] while j != -1 and pattern[j + 1] != pattern[i]: j = fail[j] if pattern[j + 1] == pattern[i]: fail[i] = j + 1 return fail[n - 1] != -1 and n % (n - fail[n - 1] - 1) == 0 return kmp(s)
5、Hash表做法
统计出每种字母的个数,根据字母的个数判断每种字母可被均分的段数,也就是求除1外的因数
将这些因数求交集,也就是整个字符串可能重复的次数。
对每一种次数进行检验,如果都不满足,返回False
class Solution(object): def repeatedSubstringPattern(self, s): """ :type s: str :rtype: bool """ hash_map = {} for c in s: if c not in hash_map: hash_map[c] = 1 else: hash_map[c] += 1 record = [] for v in hash_map.values(): record.append(set(self.getFactor(v))) temp = record[0] for i in range(1, len(record)): temp &= record[i] yes = [0] * len(temp) temp = list(temp) for j in range(len(temp)): length = len(s) / temp[j] start_list = [i * length for i in range(temp[j])] for i in range(len(start_list) - 1): if s[start_list[i]:start_list[i] + length] != s[start_list[i + 1]:start_list[i + 1] + length]: yes[j] = 1 break return 0 in yes def getFactor(self, n): result = [] for i in range(2, n + 1): if n % i == 0: result.append(i) return result