问题描述
给定一个字符串 FF,这个字符串是通过对某个初始字符串 SS 执行若干次以下操作得到的:
- 选择一个整数 KK(其中 0≤K<∣S∣0≤K<∣S∣,∣S∣∣S∣ 表示字符串 SS 的长度)
- 将 SS 从第 KK 个位置(从0开始计数)到末尾的子串追加到 SS 的末尾,即:S=S+S[K:]S=S+S[K:]
输入格式
- 输入为一个字符串 FF,仅包含小写字母,长度不超过 1000。
输出格式
- 输出一个字符串,表示可能的最短初始字符串 SS。
- 如果无法通过题目描述的操作得到字符串 FF,则输出原字符串 FF。
测试样例
样例1:
输入:str1 = "abbabbbabb"
输出:"ab"
解释:初始字符串 "ab" 可以通过以下步骤得到最终字符串:
- K=1K=1:
"a[b]"→"a[b][b]" - K=0K=0:
"[abb]"→"[abb][abb]" - K=2K=2:
"ab[babb]"→"ab[babb][babb]"
样例2:
输入:str1 = "abbbabbbb"
输出:"ab"
解释:初始字符串 "ab" 可以通过以下步骤得到最终字符串:
"a[b]" → "a[b][b]"
"ab[b]" → "ab[b][b]"
"[abbb]" → "[abbb][abbb]"
"abbbabb[b]" → "abbbabb[b][b]"
样例3:
输入:str1 = "jiabanbananananiabanbananananbananananiabanbananananbananananbananananbanananan"
输出:'jiaban'
样例4:
输入:str1 = "selectecttectelectecttectcttectselectecttectelectecttectcttectectelectecttectcttectectcttectectcttectectcttect"
输出:'select'
样例5:
输入:str1 = "discussssscussssiscussssscussssdiscussssscussssiscussssscussssiscussssscussss"
输出:'discus'
样例6:
输入:str1 = "lflsdjlskjflskjfl"
输出:'lflsdjlskjfl'
提示
- 考虑如何判断一个字符串是否可以通过题目描述的操作得到
- 可以尝试从短到长枚举可能的初始字符串
- 时间复杂度应不超过 O(n2)O(n2),其中 nn 为输入字符串的长度
我们可以先从短到长枚举所有可能的初始字符串,如abbabbbabb的话,可能的初始字符串为a,ab,abb,abba等等。再通过题目的操作,将初始字符串加长至所比对的字符串长度,如果相同的话,则满足条件直接返回,否则继续加长初始字符串直到为其本身。
核心算法实现过程:
- 枚举初始字符串:使用一个从 1 到
<font style="color:rgb(26, 32, 41);">target.length()</font>的循环来枚举可能的初始字符串长度。 - 检查生成过程:
- 初始化
<font style="color:rgb(26, 32, 41);">current</font>为当前的<font style="color:rgb(26, 32, 41);">candidate</font>。 - 使用一个
<font style="color:rgb(26, 32, 41);">while</font>循环,只要<font style="color:rgb(26, 32, 41);">current</font>的长度小于<font style="color:rgb(26, 32, 41);">target</font>的长度,就继续执行以下步骤:- 使用一个
<font style="color:rgb(26, 32, 41);">for</font>循环来枚举所有可能的<font style="color:rgb(26, 32, 41);">K</font>值。 - 对于每个
<font style="color:rgb(26, 32, 41);">K</font>,生成新的字符串<font style="color:rgb(26, 32, 41);">newStr</font>,即<font style="color:rgb(26, 32, 41);">current + current.substring(K)</font>。 - 检查
<font style="color:rgb(26, 32, 41);">newStr</font>是否等于<font style="color:rgb(26, 32, 41);">target</font>,如果是,则返回<font style="color:rgb(26, 32, 41);">true</font>。 - 检查
<font style="color:rgb(26, 32, 41);">newStr</font>是否是<font style="color:rgb(26, 32, 41);">target</font>的前缀,如果是,则更新<font style="color:rgb(26, 32, 41);">current</font>为<font style="color:rgb(26, 32, 41);">newStr</font>并退出<font style="color:rgb(26, 32, 41);">for</font>循环。 - 如果
<font style="color:rgb(26, 32, 41);">for</font>循环结束后没有找到合适的<font style="color:rgb(26, 32, 41);">K</font>,则返回<font style="color:rgb(26, 32, 41);">false</font>。
- 使用一个
- 初始化
- 返回结果:如果
<font style="color:rgb(26, 32, 41);">current</font>的长度等于<font style="color:rgb(26, 32, 41);">target</font>的长度且它们相等,则返回<font style="color:rgb(26, 32, 41);">true</font>,否则返回<font style="color:rgb(26, 32, 41);">false</font>。
public class Main {
public static String solution(String str1) {
// 从短到长枚举可能的初始字符串 candidate
for (int i = 1; i <= str1.length(); i++) {
String candidate = str1.substring(0, i);
// 检查 candidate 是否可以通过题目描述的操作生成 str1
if (canGenerate(candidate, str1)) {
return candidate;
}
}
// 如果找不到满足条件的 candidate,返回原字符串
return str1;
}
// 检查 candidate 是否可以通过题目描述的操作生成 target
private static boolean canGenerate(String candidate, String target) {
String current = candidate;
// 不断追加子串,直到 current 的长度大于等于 target 的长度
while (current.length() < target.length()) {
boolean found = false;
// 选择一个 K,追加子串
for (int K = 0; K < current.length(); K++) {
String newStr = current + current.substring(K);
if (newStr.equals(target)) {
return true;
}
if (target.startsWith(newStr)) {
current = newStr;
found = true;
break;
}
}
if (!found) {
return false;
}
}
// 如果 current 的长度等于 target 的长度,检查是否相等
return current.equals(target);
}
public static void main(String[] args) {
// Add your test cases here
System.out.println(solution("abbabbbabb").equals("ab"));
System.out.println(solution("abbbabbbb").equals("ab"));
System.out.println(solution("jiabanbananananiabanbananananbananananiabanbananananbananananbananananbanananan")
.equals("jiaban"));
System.out.println(solution(
"selectecttectelectecttectcttectselectecttectelectecttectcttectectelectecttectcttectectcttectectcttectectcttect")
.equals("select"));
System.out.println(solution("discussssscussssiscussssscussssdiscussssscussssiscussssscussssiscussssscussss")
.equals("discus"));
}
}