我正在寻找一种有效的算法,它将为我提供最长的字符串,该字符串可以由字符串列表组成。更确切地说:
给定一个包含大量字符串的文件,从文件中显示的字符串列表中找到最长的字符串,该字符串是其他一个或多个字符串的串联。
注意:答案字符串也应该属于文件中的字符串列表。
示例输入:
The
he
There
After
ThereAfter
输出:
ThereAfter
我正在寻找一种有效的算法,它将为我提供最长的字符串,该字符串可以由字符串列表组成。更确切地说:
给定一个包含大量字符串的文件,从文件中显示的字符串列表中找到最长的字符串,该字符串是其他一个或多个字符串的串联。
注意:答案字符串也应该属于文件中的字符串列表。
示例输入:
The
he
There
After
ThereAfter
输出:
ThereAfter
对列表中的字符串按长度降序对列表进行排序(列表中的第一个是最长的字符串)。快速排序以平均时间复杂度 O(nlogn) 进行排序。
然后,从左开始迭代列表中的字符串。
从字符串 S 开始,迭代其右侧的元素 s。如果 s 是 S 的子串,则从 S 中删除 s。继续向右迭代直到 S 为空,这意味着它是由列表中的项组成的。
public static class ListCompare implements Comparator<String> {
public int compare(String s1, String s2) {
if (s1.length() < s2.length())
return 1;
else if (s1.length() > s2.length())
return -1;
else
return 0;
}
}
public static String longestSurString(String[] ss) {
Arrays.sort(ss, new ListCompare ());
for (String S: ss) {
String b = new String(s);
for (String s: ss) {
if (!s.equals(b) && S.contains(s)) {
S = S.replace(s, "");
}
}
if (S.length() == 0)
return b;
}
return null;
}
让我们为字符串编号S1, S2, ..., Sn
如果我正确理解问题陈述,而不是Si
成为答案的候选者,它必须等于一些
Sj_1, Sj_2, ..., Sj_k
where forall的串联x in 1..k: i != j_x
。那必须是它不是其成员Si
的字符串子集的串联。
鉴于此,将所有字符串添加到 trie 中。这将找到所有前缀对,即(Si, Sj_1)
上述所有。从渲染中删除Sj_1
前缀Si
会生成一个新字符串T
,该字符串必须等于,或者可以通过在 trie 中Sj_k
搜索来类似地减少。Sj_2
使用 Trie & HashMap 数据结构的最佳解决方案:
我们需要首先存储所有字符串,然后检查前缀哪个单词长度更大。
public class TrieNode {
private HashMap<Character, TrieNode> children;
private boolean isWord;
public TrieNode() {
children = new HashMap<>();
isWord = false;
}
public void add(String s) {
HashMap<Character,TrieNode> temp_child = children;
for(int i=0; i<s.length(); i++){
char c = s.charAt(i);
TrieNode trieNode;
if(temp_child.containsKey(c)){
trieNode = temp_child.get(c);
}else{
trieNode = new TrieNode();
temp_child.put(c, trieNode);
}
temp_child = trieNode.children;
//set leaf node
if(i==s.length()-1)
trieNode.isWord = true;
}
}
public boolean isWord(String s) {
TrieNode trieNode = searchNode(s);
if(trieNode != null && trieNode.isWord)
return true;
else
return false;
}
public TrieNode searchNode(String s){
HashMap<Character, TrieNode> temp_child = children;
TrieNode trieNode = null;
for(int i=0; i<s.length(); i++){
char c = s.charAt(i);
if(temp_child.containsKey(c)){
trieNode = temp_child.get(c);
temp_child = trieNode.children;
}else{
return null;
}
}
return trieNode;
}