String 寻找一个;针头;“在一个两维空间中”;“干草堆”;

String 寻找一个;针头;“在一个两维空间中”;“干草堆”;,string,algorithm,search,String,Algorithm,Search,我想这是最常见的面试问题之一,但我无法以有效的方式解决它(高效意味着时间复杂度较低,并使用合适的数据结构)。 问题是这样的: 如果有一个字符的mxn矩阵(比如haystack)和一个给定的长度为k的char字符串(指针)。编写一个程序来检查草堆中是否有针。请注意,我们只需要从上到下或从左到右搜索干草堆。 比如说 Haystack ahydsfd sdflddl dfdfd dfdl uifddffdhc Needle: hdffi Output: Yes Found!! 蛮力方法的时间复

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

Haystack

ahydsfd
sdflddl
dfdfd
dfdl
uifddffdhc

Needle:
hdffi

Output:
Yes Found!!

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

原始蛮力是O(m*n*k)。下面是一些优化的想法

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

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

高效字符串搜索算法
这是一个研究得很好的问题,有几种线性时间算法,如和。使用线性时间字符串搜索算法搜索每一行和每一列,将时间复杂度降低到O(m*n)。这可能就是面试官想要的

利用短行

我注意到并非所有的行都有相同的长度。当您查找垂直匹配时,只要指针“弹出”麻袋,您就可以停止搜索该行,因为沿着该行的所有指针也将退出麻袋,因此无法匹配。

您可以将第一个字符的搜索限制为n-k列和m-k行。一旦发现,答案需要2(k-1)个比较。

从左到右从上到下分别搜索蚂蚁有什么不对?连续两次面试官告诉我有更好的方法。我不确定“更好”是什么意思。@javacoder990:你没有问面试官他们的意思吗?@n.m:可能与缓存性能有关吧?无论如何,自上而下的搜索将是一个缓存杀手,但通过将其与从左到右的搜索相结合,您可能可以稍微减少未命中的总数。@Steve Jessop:在“最常见的面试问题之一”中?当然,如果针的长度为x个字符,则可以对其进行优化,使其复杂性为(m-x-1)*n!问题在于较长的针。通过整个扫描确定最稀有的字母意味着你访问每个单元格,这在大多数情况下是工作量最大的,除了一块几乎只包含(例如)d的板,针以d开头,并且大部分由d组成。但是如果没有关于文本的进一步知识(即使是字符的分布,x语言文本中的字符标记,…),分析文本可能需要比开始工作更多的时间。只要矩阵大小未知,即使是100个字符的随机样本也可能不可用。我们也不知道它是否具有代表性。