寻找最长复合词的时间复杂性

时间:2015-01-03 17:40:03

标签: algorithm big-o time-complexity

我指的是算法问题:

http://www.ardendertat.com/2012/06/15/programming-interview-questions-28-longest-compound-word/

  

给定一个排序的单词列表,找到最长的复合单词   通过连接列表中的单词构建的列表。对于   例如,如果输入列表是:['cat','cats','catsdogcats',   'catxdogcatsrat','dog','dogcatsdog','hippopotamuses','rat',   'ratcat','ratcatdog','ratcatdogcat']。然后是最长的复合词   是'ratcatdogcat'有12个字母。注意最长的个体   单词是'catxdogcatsrat'和'hippopotamuses',有14个字母,但是   他们并没有完全用其他词语构建。前者有一个额外的   'x'字母,后者是一个单独的单词本身不是一个复合词   字。

我按如下方式实现了算法:

  1. 从输入列表中的所有单词构造一个Trie。每个节点代表一个字符,单词的结尾通过设置isTerminal=true

  2. 进行标记
  3. 现在我有另一种方法来检查每个输入字,以找出它所构成的组件数量(比如复合长度)。例如,在上面的示例中,ratcatdogcat由输入列表ratcatdogcat中的单个词组成。我这样做是通过递归地解析输入单词的有效前缀并找到单词其余部分的复合长度,即解析rat并获得catdogcat的复合长度。如果休息的复合长度为zero,则表示休息不是有效的构造,我尝试下一个前缀ratcat并递归dogcat

  4. 伪代码如下所示:

    Node {
      Character ch
      Map<Character, Node> children
      boolean isTerminal
    }
    
    int getCompoundLength(word) {
    
      if (dpTable.contains(word))
        return dpTable.get(word)
    
      dpTable.put(word, 0) // memoize word to compound length
    
      Node current = root;
      for (i=0 to word.length) {
        ch = word[i]
        if (!current.children.contains(ch)) // invalid character
          return 0;
    
        current = current.children.get(ch)
    
        if (!current.isTerminal) // not a valid prefix yet
          continue
    
        lenRest = getCompoundLength(word.substring(i+1));
    
        if (lenRest != 0) { // rest of the string is valid
          dpTable.put(word, lenRest+1)
          return lenRest + 1
        }
      }
    
      // Could not split the word into multiple components.
      // Check if word is a valid word at least.
      if (current.isTerminal) {
        dpTable.put(word, 1)
        return 1;
      }
    

    我知道构造trie需要O(W),其中W是输入字的总数。但我不清楚如何计算getCompoundLength方法的运行时间。感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

你的理解是错误的。在单词中插入一个单词具有该单词长度的运行时间,因此构建该单词的时间为O(W*s),其中s是该单词的平均大小。

查找特里结尾的单词是最差的O(s),其中s是该单词的长度。

至于你的getCompoundLength方法,你需要提出最悲观的可能输入。请考虑以下示例:

a
aa
aaa
aaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab

最后一个字不是复合词。但是你刚刚想出那个指数回溯问题......

(真实世界的正则表达式实现在黑桃中有这个问题。它们在大多数字符串上都能正常工作,但是有一些病理输入会让它们发出哔哔声。)