问题如下:你从一个2个字母的单词开始,你可以在单词的正面和背面附加字母。你必须通过在2个字母单词的正面和背面附加字母来返回字典中存在的最长单词,并且你形成的每个新单词也必须在字典中;
例如: 开始:'at'
Dict:[帽子,聊天,聊天,老鼠,率,橙色]
输出:'聊天',因为:at - >帽子 - >聊天 - >聊天
我的代码如下:
public static String longest(ArrayList<String> input) {
return helper('at', dict);
}
public static String helper(String in, ArrayList<String> dict) {
ArrayList<String> maxes = new ArrayList<String>();
for (char a = 'a'; a < 'z'; a++) {
String front = Character.toString(a) + in;
String back = in + Character.toString(a);
if (dict.contains(front)) {
maxes.add(helper(front, dict));
}
if (dict.contains(back)) {
maxes.add(helper(back, dict));
}
}
if (maxes.size() == 0) {
return in;
}
String word = "";
for (String w : maxes) {
if (w.length() > word.length()) {
word = w;
}
}
return word;
}
我想知道这个算法的时间复杂度是多少?我不能为我的生活弄明白。
答案 0 :(得分:2)
答案很大程度上取决于您的词典( n 单词,其最大可达长度 L &lt; = n +1)以及您的数据存储它的结构。每次调用helper
(没有递归调用)都是O( n L ),dict
是ArrayList
,而哈希表是O(< em> L )(没有不可能的碰撞)。 (字典中可能存在很长时间无法访问的单词,但是仍然需要花费O( L )才能与它们进行比较,因为您的试用单词不能更长。)
关于helper
的调用次数:这只是在通过前置/附加字母相关的单词树上进行深度优先搜索。因此,它是O( v ),其中 v 是所访问的顶点数。各种输入词的 v 值也取决于您的词典: v &lt; = n ,当然,通常要少得多。例如:在/usr/share/dict/words
中使用全部是ASCII字母的71813行(并忽略大小写),所考虑的最多单词是593(氩气中的“Ar”)。
最坏情况的字典将使其所有单词形成链“ab”,“abc”,“abcd”,等。。您访问每个单词的总成本为O( vn L )= O( n ^ 3)(O( v L )= O ( n ^ 2)与哈希表)。现实的词典会快得多,不仅因为 L 较小,而且因为 v ;遗憾的是,确切的加速很难分析。假设 L 是Θ(log( n )),这可能是合理的;作为 n 的函数, v 没有有意义的渐近表达式,因为现实字典没有任意大的 n