【问题标题】:Searching for a "needle" in a two dimnesional "haystack" [closed]在二维“干草堆”中搜索“针”[关闭]
【发布时间】:2012-03-19 19:45:28
【问题描述】:

我想这是最常见的面试问题之一,但我无法以有效的方式解决它(有效意味着更小的时间复杂度和使用合适的数据结构)。 问题是这样的: 如果有一个m x n matrix 的字符(比如干草堆)和一个给定的char 长度为 k 的字符串(针)。编写一个程序来检查干草堆是否包含针。请注意,我们只需要从上到下或从左到右搜索干草堆。 例如

Haystack

ahydsfd
sdflddl
dfdfd
dfdl
uifddffdhc

Needle:
hdffi

Output:
Yes Found!!

【问题讨论】:

  • 从左到右的ant从上到下分别搜索有什么问题?
  • 连续两位面试官告诉我,有更好的方法。我不确定,“更好”是什么意思。
  • @javacoder990:你没问面试官的意思吗?
  • @n.m.:可能与缓存性能有关吗?无论如何,自上而下的搜索将成为缓存杀手,但您可以通过将其与从左到右的搜索混合来稍微减少未命中的总数。
  • @Steve Jessop:在“最常见的面试问题之一”中?

标签: string algorithm search


【解决方案1】:

蛮力法的时间复杂度最差,为 m*n。也就是说,如果 needle 是单个字符,我们开始逐行或逐列解析矩阵。

【讨论】:

  • 当然如果 needle 的长度为 x 字符,那么它可以优化为具有 (m-x-1)*n 的复杂度!
  • 问题在于针较长。
【解决方案2】:

天真的蛮力是 O(m*n*k)。以下是一些优化思路。

单一搜索
不要先搜索水平,然后再搜索垂直,而是同时进行。每次您发现针的第一个字母出现时,查找从该字母开始的水平和垂直匹配。这不会提高时间复杂度,但可以将时间减半,因为您只会查看一次糟糕的开始。

稀有字母
与其寻找针的第一个字母,不如寻找针中出现的最稀有的字母。这可以快速排除很多可能的匹配(尽管它不会提高最坏情况的时间复杂度)。要确定哪些字母最稀有,请扫描整个板或使用随机抽样。

高效的字符串搜索算法
String searching 是一个经过充分研究的问题,有几种线性时间算法,例如Knuth–Morris–PrattBoyer–Moore。使用线性时间字符串搜索算法搜索每一行和每一列将时间复杂度降低到 O(m*n)。这可能是面试官所追求的。

利用短行
我注意到并非所有行都具有相同的长度。当您查找垂直匹配项时,您可以在针从袋中“弹出”时立即停止搜索该行,因为沿该行更远的所有针也会退出袋,因此无法匹配。

【讨论】:

  • 通过整个扫描确定最稀有的字母意味着您访问每个单元格,在大多数情况下这是最多的工作量,除了几乎只包含 - 例如 - 'd's , 并且针头以 d 开头并且也主要由 'd's 组成。但是,如果没有关于文本的进一步知识(甚至字符分布、来自语言 x 的文本中的字符标记……),分析文本可能需要比刚开始工作更多的时间。只要矩阵大小未知,即使是 100 个字符的随机样本也可能不可用。我们也不知道它是否具有代表性。
【解决方案3】:

您可以将第一个字符的搜索限制为 n-k 列和 m-k 行。找到后,需要进行 2(k-1) 次比较才能得到答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 2017-11-07
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    相关资源
    最近更新 更多