问题描述
- 输入一个字符串,判断其是否完全循环,若是循环的,输出最短的循环子串,否则输出空
"" - 如输入
abababab,输出ab;输入ab则输出""
输入格式
- 合法字符串 如
abcabcabcabcaaa
输出格式
- 最短的循环子串
"abc""a"
输入样例
"abcabcabcabc"
输出样例
"abc"
数据范围
测试数据集
解答思路
-
理解问题:
-
想象你有一串珠子,每个珠子都有一个字母。我们要看看这串珠子是不是由某个小珠子重复多次组成的。如果是,我们就找出这个小珠子;如果不是,我们就说没有这样的小珠子。
-
-
找小珠子:
-
我们从最小的珠子开始找,看看这个小珠子能不能重复多次组成整串珠子。
-
比如,如果整串珠子是
abcabcabcabc,我们先看看最小的珠子a能不能重复多次组成整串珠子。显然不行,因为a重复多次只能组成aaaa。 -
然后我们看看两个珠子的组合
ab,再看看三个珠子的组合abc。我们发现abc重复四次正好是abcabcabcabc,所以abc就是我们要找的小珠子。
-
-
检查所有可能的小珠子:
-
我们从1个珠子开始,一直检查到整串珠子的一半长度。因为如果小珠子比整串珠子的一半还长,那它就不可能重复多次组成整串珠子了。
-
-
返回结果:
-
如果我们找到了一个小珠子,它能重复多次组成整串珠子,我们就把这个小珠子告诉别人。
-
如果找遍了所有可能的小珠子都没有找到,我们就说没有这样的小珠子。
-
具体代码
public class Main {
public static String solution(String inp) {
for (int i = 1; i <= inp.length() / 2; i++) {
// 检查是否可以通过重复子串来构造原始字符串
String substring = inp.substring(0, i);
if (inp.equals(substring.repeat(inp.length() / i))) {
return substring;
}
}
return "";
}
public static void main(String[] args) {
System.out.println(solution("abcabcabcabc").equals("abc"));
}
}
解释代码
-
遍历可能的子串长度:
-
for (int i = 1; i <= inp.length() / 2; i++)-
我们从1开始,遍历到字符串长度的一半。因为一个子串至少需要重复两次才能构成原始字符串。
-
-
-
获取当前长度的子串:
-
String substring = inp.substring(0, i);-
使用
substring方法获取从字符串开头到第i个字符的子串。
-
-
-
检查子串是否可以重复构造原始字符串:
-
if (inp.equals(substring.repeat(inp.length() / i)))-
使用
repeat方法重复当前子串,重复的次数是原始字符串长度除以子串长度。 -
检查重复后的字符串是否等于原始字符串。
-
-
-
返回结果:
-
return substring;-
如果找到符合条件的子串,返回这个子串。
-
-
return "";- 如果遍历完所有可能的子串长度都没有找到符合条件的子串,返回空字符串
""。
- 如果遍历完所有可能的子串长度都没有找到符合条件的子串,返回空字符串
-
感悟与思考
这样的输入字符串判断是否完全循环的题还是做了挺多的,所以一开始见到的时候,在开始编写代码之前,理解问题的本质非常重要,也就是说这个问题要求我们找到一个字符串的最短循环子串。理解了这一点,于是设计出了这样的算法。
从最小的子串开始,逐步增加子串的长度,检查是否可以通过重复该子串来构造原始字符串。这种逐步推理的方法帮助我们系统地解决问题。
在编写代码时,简洁性是一个重要的考虑因素。我使用了 substring 和 repeat 方法,这些方法使得代码更加简洁和易读。
在编写代码时,处理边界条件是非常重要的。例如,我们只遍历到字符串长度的一半,因为一个子串至少需要重复两次才能构成原始字符串。这样子减少循环次数,也能够节省时间哈哈哈哈