一探详细题目
小M在研究字符串时发现了一个有趣的现象:某些字符串是由一个较短的子串反复拼接而成的。如果能够找到这个最短的子串,便可以很好地还原字符串的结构。你的任务是给定一个字符串,判断它是否是由某个子串反复拼接而成的。如果是,输出该最短的子串;否则,输出空字符串""。
例如:当输入字符串为 abababab 时,它可以由子串 ab 反复拼接而成,因此输出 ab;而如果输入 ab,则该字符串不能通过子串的重复拼接得到,因此输出空字符串。
题目中所给的测试案例:
测试样例
样例1:
输入:
inp = "abcabcabcabc"
输出:'abc'
样例2:
输入:
inp = "aaa"
输出:'a'
样例3:
输入:
inp = "abababab"
输出:'ab'
样例4:
输入:
inp = "ab"
输出:''
样例5:
输入:
inp = "abcdabcdabcdabcd"
输出:'abcd'
样例6:
输入:
inp = "b"
输出:''
二思题目求解
2.1 题目分析
这道题目要求我们判断一个给定的字符串是否是由某个较短的子串反复拼接而成的,如果是,则返回这个最短的子串;如果不是,则返回空字符串。
分析步骤:
-
理解题意:首先明确题目要求,即找到一个最短的子串,使得该子串重复拼接后可以得到原字符串。
-
确定思路:
- 遍历所有可能的子串长度(从1到字符串长度的一半)。
- 对于每个可能的子串长度,检查该子串是否能够整除整个字符串,并且重复拼接后是否与原字符串相同。
- 如果找到符合条件的子串,则返回该子串。
- 如果遍历完所有可能的子串长度都没有找到符合条件的子串,则返回空字符串。
-
考虑边界情况:
- 如果字符串长度为1,则它自身就是一个子串,但根据题目要求,这种情况下应该返回空字符串,因为不能通过重复一个字符来“拼接”成原字符串(这里“拼接”意味着至少重复一次以上)。
- 如果字符串长度为0,则直接返回空字符串。
三 MAKE Code Thought
3.1 题目求解方法1
使用字符串拼接和比较
实现代码
public class Solution { public static String repeatedSubstringPattern(String s) { int n = s.length(); for (int len = 1; len <= n / 2; len++) { if (n % len == 0) { String substring = s.substring(0, len); StringBuilder sb = new StringBuilder(); for (int i = 0; i < n / len; i++) { sb.append(substring); } if (sb.toString().equals(s)) { return substring; } } } return ""; } public static void main(String[] args) { // 测试用例 System.out.println(repeatedSubstringPattern("abcabcabcabc")); // 输出 "abc" System.out.println(repeatedSubstringPattern("aaa")); // 输出 "a" System.out.println(repeatedSubstringPattern("abababab")); // 输出 "ab" System.out.println(repeatedSubstringPattern("ab")); // 输出 "" System.out.println(repeatedSubstringPattern("abcdabcdabcdabcd")); // 输出 "abcd" System.out.println(repeatedSubstringPattern("b")); // 输出 "" } }
3.2 题目求解方法2
public class Solution { public static String repeatedSubstringPattern(String s) { int n = s.length(); for (int len = 1; len <= n / 2; len++) { if (n % len == 0) { String substring = s.substring(0, len); if (s.equals(substring.repeat(n / len))) { return substring; } } } return ""; } // main 方法同上 }
四:总结
- 字符串操作:包括字符串的截取(
substring)、拼接(+或StringBuilder)、重复(repeat,Java 11及以上)等。 - 循环和条件判断:用于遍历所有可能的子串长度,并检查每个子串是否满足条件。
- 模运算:用于检查字符串长度是否能被当前子串长度整除。
反思
- 性能优化:虽然上述算法的时间复杂度为O(n^2)(在最坏情况下,需要遍历所有可能的子串长度,并且对于每个子串长度,可能需要拼接和比较字符串),但对于大多数实际情况来说,这个算法是足够高效的。如果需要进一步优化,可以考虑使用哈希函数或滚动哈希来检测重复模式。
- 边界情况处理:在处理字符串问题时,总是要注意边界情况,如空字符串、单个字符的字符串等。
- 代码可读性:尽量使代码简洁明了,便于理解和维护。例如,使用
repeat方法可以使代码更加直观和易读。 - 算法多样性:尝试用不同的方法解决问题,可以拓宽思路,提高解决问题的能力。例如,除了上述的字符串拼接和比较方法外,还可以考虑使用字符串哈希、KMP算法(Knuth-Morris-Pratt)等高级技巧来解决这个问题。