Algorithm 如何在字母矩阵中找到单词

Algorithm 如何在字母矩阵中找到单词,algorithm,language-agnostic,Algorithm,Language Agnostic,这是电话采访中问我的另一个问题: 给定一本字典和一个纵横字谜(2d字符矩阵),找出所有可以在纵横字谜中找到的字典单词 我所能想到的就是对字典进行哈希运算,在填字游戏中找到所有可能的单词并搜索哈希。我无法将其全部优化 必须承认,微软的面试问题很难回答:( 请给我台词让我思考。怎么样: 为字典建立搜索树(每个字母一级) 对于网格中的每个位置,开始在索引中搜索,每次搜索一个字符,然后沿每个允许的方向继续搜索,直到索引中没有任何条目,或者到达网格边界 我认为哈希在这里不是一个非常有用的优化。假设字典

这是电话采访中问我的另一个问题:

给定一本字典和一个纵横字谜(2d字符矩阵),找出所有可以在纵横字谜中找到的字典单词

我所能想到的就是对字典进行哈希运算,在填字游戏中找到所有可能的单词并搜索哈希。我无法将其全部优化

必须承认,微软的面试问题很难回答:(

请给我台词让我思考。

怎么样:

  • 为字典建立搜索树(每个字母一级)
  • 对于网格中的每个位置,开始在索引中搜索,每次搜索一个字符,然后沿每个允许的方向继续搜索,直到索引中没有任何条目,或者到达网格边界

我认为哈希在这里不是一个非常有用的优化。

假设字典包含n个平均长度为k的单词,而矩阵包含m²字符

  • 将字典预处理为a(又名trie)。-O(kn)
  • 对于矩阵中的每个位置,在trie.-O(m³)中上下查找字符串
  • 总时间:O(最大(kn,m³))


    在现实的单词搜索中,在矩阵中找到的单词的平均长度更像k而不是m,因此所用的时间是O(k max(n,m²))。

    您的答案有什么问题

    • 字典是经过排序的,所以我想我应该将字典中的单词排列成一个字母。这会有帮助,因为可能有很多单词的前缀也是一个单词。排序有助于(最少)构建时间

    • 然后在纵横填字游戏中寻找所有可能的单词。当你提取一个潜在单词的字符时,你正在沿着trie走——这样你会找到第一个以某组字符开头的单词,但也会在正确的位置继续找到以相同字符开头的其他单词


      • 最合适的解决方案在很大程度上取决于您希望处理的约束。您的字典有多大?您的纵横字谜有多大

        我建议看一看。你可以将所有字典中的单词插入其中。然后在后缀树中搜索行、列和对角线。对于行,从树的根开始搜索每行的第一个字母,并在通过行时在树中迭代。如果需要,从右到左执行相同操作。类似的柱和对角线的公差

        树结构是O(N)并消耗O(N)空间,其中N是字典的字符大小。搜索将花费O(PQ)时间,其中纵横字谜的大小为PxQ。给出O(N+PQ)的总体运行时间和O(N)的空间


        但问题是,后缀树很难实现。它们真的很难实现。因此,您可能更喜欢使用简单的后缀树,它将为您提供O(N+PQ(max(p,Q))的总运行时间。

        这个问题正是如何玩Boggle

        这个过去的问题已经足够了


        玩得开心…

        我会将字典编译成DFA,识别字典中的单词,然后在字母矩阵的行、列和对角线上运行。应该是
        O(m+n)
        ,其中
        m
        是字典的字符长度,
        n
        是区域(w*h)一个散列?你是说一个散列trie?约束条件是什么?每个字符必须与填字游戏中的前一个字符相邻吗?伊加尼奥:我是说普通的散列表。好吧,这三个答案都给出了相同的算法:)要么我们都接受过微软的采访,要么我们都很有同感。或者说傻瓜很少有不同之处@保罗或我们以前见过的常见问题(或至少类似的问题):但问题要求你使用字典+他用了一本字典。要从中创建搜索树:)+1定义搜索树?什么种类?@marcog:在每个嵌套级别,每个不同的字母都有一个分支。因此,如果你的词典包含“foo”、“bar”和“baz”三个词条,那么你的顶层就有“f”和“b”。“f”分支将包含一个分支“o”,而“o”又包含一片叶子,即第二个“o”。“b”分支将包含一个分支“a”,带有两个叶子“r”和“z”。@mustafabar:由于键值集合不符合实际情况,我认为可以安全地假设“字典”实际上是指“无序的字符串集合”。后缀树产生更快的查找。请看我的答案。@marcog,因为在许多情况下,我们查找的单词比上次查找的单词长一个字母,所以查找时间可能比前缀尝试的“平均”时间要好。不过,我不确定它的无症状行为是什么。你能更详细地介绍一下搜索的工作原理吗?“我不太明白如何将纵横字谜搜索转化为一种高效的后缀树操作。”保罗的面试问题通常与最坏情况分析和一般情况分析一样重要。后缀树永远不会比尝试更糟糕,在很多情况下比尝试更好。如果匿名downvoter能解释我在这个答案中的错误,我很乐意尝试更正。你能告诉我你是如何得出aysmtotic运行时的吗?查看维基文章,他们解释了树的运行时。对于后缀树搜索,对于每一行/列/对角线,每个字符执行一个查询,因为它可以非常有效地动态换行到一个新的部分词,即3PQ,因此为O(PQ)。对于尝试,您必须开始在6个方向的每个字符处搜索trie。因为有PQ字符,一个单词的长度最差可能是max(P,Q),所以有6PQ(max(P,Q)),因此有PQ(max(P,Q))。