该问题有有三种解法,第一种就是常见的枚举,双重for循环,时间复杂度通常不如人意,On2
第二种则是巧妙利用这种结构的特性进行处理
第三种是经典的KMP算法
枚举
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| bool repeatedSubstringPattern(string s) { int n = s.size(); for (int i = 1; i * 2 <= n; ++i) { if (n % i == 0) { bool match = true; for (int j = i; j < n; ++j) { if (s[j] != s[j - i]) { match = false; break; } } if (match) { return true; } } } return false; }
|
特性
如果给定的string符合要求,则从索引1开始对合并后的string进行查找操作后,不会在第二个拼接string那里获取到结果
1 2
| return (s + s).find(s, 1) != s.size();
|
KMP算法
过于经典和麻烦,不做赘述
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| bool kmp(const string& query, const string& pattern) { int n = query.size(); int m = pattern.size(); vector<int> fail(m, -1); 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; } } int match = -1; for (int i = 1; i < n - 1; ++i) { 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); }
|