包含三个字符串的最短字符串
难度:
标签:
题目描述
Given three strings
a
, b
, and c
, your task is to find a string that has the minimum length and contains all three strings as substrings.
If there are multiple such strings, return the lexicographically smallest one.
Return a string denoting the answer to the problem.
Notes
- A string
a
is lexicographically smaller than a stringb
(of the same length) if in the first position wherea
andb
differ, stringa
has a letter that appears earlier in the alphabet than the corresponding letter inb
. - A substring is a contiguous sequence of characters within a string.
Example 1:
Input: a = "abc", b = "bca", c = "aaa" Output: "aaabca" Explanation: We show that "aaabca" contains all the given strings: a = ans[2...4], b = ans[3..5], c = ans[0..2]. It can be shown that the length of the resulting string would be at least 6 and "aaabca" is the lexicographically smallest one.
Example 2:
Input: a = "ab", b = "ba", c = "aba" Output: "aba" Explanation: We show that the string "aba" contains all the given strings: a = ans[0..1], b = ans[1..2], c = ans[0..2]. Since the length of c is 3, the length of the resulting string would be at least 3. It can be shown that "aba" is the lexicographically smallest one.
Constraints:
1 <= a.length, b.length, c.length <= 100
a
,b
,c
consist only of lowercase English letters.
代码结果
运行时间: 139 ms, 内存: 16.0 MB
/*
* 思路:
* 1. 通过Java Stream API处理多个可能的字符串组合
* 2. 合并每两个字符串,生成包含它们的最短字符串
* 3. 比较所有可能的结果,选择最短且字典序最小的一个
*/
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class SolutionStream {
private static String merge(String s1, String s2) {
for (int i = 0; i < s1.length(); i++) {
if (s2.startsWith(s1.substring(i))) {
return s1.substring(0, i) + s2;
}
}
return s1 + s2;
}
public static String findShortestSuperstring(String a, String b, String c) {
List<String> combinations = Arrays.asList(
merge(merge(a, b), c),
merge(merge(a, c), b),
merge(merge(b, a), c),
merge(merge(b, c), a),
merge(merge(c, a), b),
merge(merge(c, b), a)
);
return combinations.stream()
.sorted(Comparator.comparingInt(String::length).thenComparing(String::compareTo))
.collect(Collectors.toList())
.get(0);
}
public static void main(String[] args) {
System.out.println(findShortestSuperstring("abc", "bca", "aaa")); // 输出: "aaabca"
System.out.println(findShortestSuperstring("ab", "ba", "aba")); // 输出: "aba"
}
}
解释
方法:
此题解采用的方法是首先定义一个合并两个字符串的函数,该函数通过检查字符串的前缀和后缀是否相匹配来找到最短的合并方式。如果一个字符串是另一个的子串,则直接返回包含关系中的较大字符串。如果不是,函数尝试寻找最大的公共前后缀,并在此基础上合并两个字符串。主函数中,通过考虑所有字符串的排列组合,利用这个合并函数逐步合并三个字符串,保证每次合并都尝试得到最短的可能字符串。最终比较所有可能的合并结果,选择长度最短的,如果长度相同则选择字典序最小的字符串。
时间复杂度:
O(n^2)
空间复杂度:
O(n)
代码细节讲解
🦆
在合并函数中使用前缀和后缀匹配来确定合并方式的原理是什么?能否详细解释其有效性?
▷🦆
合并函数中如果没有找到公共的前缀或后缀,直接将两个字符串拼接,这种情况下是否可能错过更优的合并结果?
▷🦆
题解中提到了对所有字符串排列进行合并操作,这种方法在哪些情况下可能不是最优的?
▷🦆
在选择最短字符串结果时,如何处理多个结果长度相同但字典序不同的情况?具体的比较逻辑是怎样的?
▷