用于在单词搜索网格上查找单词的最快算法

时间:2014-11-07 04:01:57

标签: algorithm

我接受了一位软件开发人员的采访。这是一次电话采访。被问到这一点,这一直困扰着我

面试官让我想出一个在单词搜索网格上找到单词的一般方法。为简单起见,无需担心内存限制或在网格上对角搜索(从左到右,从上到下)。

我能想到的最好的方法是在网格程序启动时创建一个哈希映射(每次调用单词搜索之前)...让它创建一个字符的哈希映射 = > 行,列索引。这样你就可以在O(1)时间内执行初始扫描。然后从那里基本上扫描从左到右或从上到下。

我从他那里得到的印象是有一个更好的解决方案,而我还没有。解决此类问题的最快算法是什么?

3 个答案:

答案 0 :(得分:0)

如果内存不是问题我可以预处理数据,那么我会:

  1. 以行主顺序创建网格的字符串表示形式。这是为了横向搜索。
  2. 以列主顺序创建网格的字符串表示形式,以便垂直搜索。
  3. 当给出要搜索的单词时,我会使用标准搜索算法(KMP,Boyer-Moore等)来:

    1. 在行主要字符串中搜索单词。
    2. 反转单词并搜索行主要字符串。
    3. 在列主要字符串中搜索单词。
    4. 反转单词并在列主要字符串中搜索。
    5. 在简单性,内存使用率和速度之间取得了良好的平衡。事实上,它很简单,因为你不需要实现搜索算法。只需使用运行时库提供的任何内容。

      当然,您可以轻松修改标准搜索算法,将二维网格视为一维字符串,而无需提前进行转换。这比较复杂,在搜索方面比预处理稍慢,但需要更少的内存。

      使用单次扫描执行此操作变得复杂。但是你可以在一次扫描中轻松地进行水平搜索(即从左到右和从右到左)。并且在单次扫描中进行垂直搜索。你只是在一次通过中搜索两个不同的字符串:单词和单词的反转版本。

答案 1 :(得分:0)

如果预处理数据不计入时间,则可以准备一个向量数组,其中包含每个字母的位置。因此,给定第一个字母后,您将直接转到出现该字母的位置,然后检查4个(或8个)方向以查找其余字母。

在另一个答案的注释中,@ deAtog似乎建议使用数组查找第一个和最后一个字母的位置。但是,即使对于中等大小的网格,每个字母也可能出现4次以上,因此仅检查4个方向可能会更快。

您可以将数组的构想扩展到一个数字数组(2个字母的组合)。语法图包含语法图的位置和方向现在,给定单词的前2个字母,您将直接转到这些字母的位置和方向。对于单字母单词,您只需检查所有以字母开头的字母。我认为这提供了大小和速度的完美结合。

如果您真的不关心空间,则可以一直扩展数组的概念,以使例如50,000个最受欢迎的单词的位置和方向保持一致。现在,如果您得到该列表中的单词,则可以在找到该单词在一致性中所需的时间内找到它。

但我认为这种协调性过高。将图映射到位置/方向可能是速度和空间的良好折衷。

最后,如果预处理确实很重要,而您只想查找一个单词,则可以对蛮力方法应用技巧:将网格存储在边框周围,并留有多余的空格。这些包含一个非字母。这样做意味着您不必检查数组边界。如果您超出网格边缘,则该值将与单词中的任何字母都不匹配,因此您将停止在此处进行检查。

答案 2 :(得分:-1)

我想说他希望你推动澄清。如果您正在搜索单词,那么我同意您的方法。如果您正在搜索单个单词,那么对第一个字母进行线性搜索,然后在每个方向上搜索其余单词将会更快。