Example 41
重复的子字符串
题目概述:给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。
示例 1:
输入: s = "abab"
输出: true
解释: 可由子串 "ab" 重复两次构成。
示例 2:
输入: s = "aba"
输出: false
示例 3:
输入: s = "abcabcabcabc"
输出: true
解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)
解题步骤:如果一个长度为n的字符串s可以由它的一个长度为n'的子串s'重复多次构成,那么:n一定是n'的倍数;s'一定是s的前缀;
对于任意的i∈[n',n),有s[i]=s[i−n']。
也就是说,s中长度为n'的前缀就是s',并且在这之后的每一个位置上的字符s[i],都需要与它之前的第n'个字符s[i−n']相同。
因此,我们可以从小到大枚举n',并对字符串s进行遍历,进行上述的判断。注意到一个小优化是,因为子串至少需要重复一次,所以n'不会大于n的一半,我们只需要在[1,] 的范围内枚举n'即可。
示例代码如下;
public class RepeatedSubstringPattern { /** * 给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。 * 示例 1: * 输入: s = "abab" * 输出: true * 解释: 可由子串 "ab" 重复两次构成。 * 示例 2: * 输入: s = "aba" * 输出: false * 示例 3: * 输入: s = "abcabcabcabc" * 输出: true * 解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。) * 来源:力扣(LeetCode) * 链接:https://leetcode.cn/problems/repeated-substring-pattern */ public static void main(String[] args) { RepeatedSubstringPattern rsp = new RepeatedSubstringPattern(); System.out.println(rsp.repeatedSubstringPattern("abab")); // true } /** * 官方 * * @param s * @return */ public boolean repeatedSubstringPattern(String s) { int n = s.length(); for (int i = 1; i * 2 <= n; ++i) { if (n % i == 0) { boolean match = true; for (int j = i; j < n; ++j) { if (s.charAt(j) != s.charAt(j - i)) { match = false; break; } } if (match) { return true; } } } return false; } }