用于在字典

时间:2017-09-22 07:17:35

标签: java string recursion time time-complexity

问题如下:你从一个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;
  }

我想知道这个算法的时间复杂度是多少?我不能为我的生活弄明白。

1 个答案:

答案 0 :(得分:2)

答案很大程度上取决于您的词典( n 单词,其最大可达长度 L &lt; = n +1)以及您的数据存储它的结构。每次调用helper(没有递归调用)都是O( n L ),dictArrayList,而哈希表是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