子线性时间内的二维数组搜索

时间:2013-09-20 05:03:33

标签: algorithm

今天我在接受采访时被问到以下问题:

给定一个n乘n的整数数组,它不包含从左到右以及从上到下增加的重复项和值,提供一种算法来检查给定值是否在数组中。

我提供的答案类似于此主题中的答案:
Algorithm: efficient way to search an integer in a two dimensional integer array?

该解决方案是O(2n),我认为这是最佳解决方案。

然而,采访者告诉我,有可能在子线性时间内解决这个问题。我已经绞尽脑汁想要如何做到这一点,但我什么都没有。

子线性解是可能的,还是最优解?

1 个答案:

答案 0 :(得分:4)

要问自己的是,每个比较给你的信息是什么?它让你消除“左上方”或“右下方”的矩形。

假设您在'x'处进行比较,它会告诉您正在寻找的内容更大:

XXX...
XXX...
XXx...
......
......

'x' - 已检查的空间
'X' - 检查显示这不是您数据的可能位置
'。' - 仍然未知

您必须以智能方式使用此信息来检查整个矩形。

假设您在中间列上以这种方式进行二进制搜索...

你会得到像

这样的结果
XXX...
XXX...
XXX...
XXXXXX
...XXX
...XXX

两个矩形空间留有半宽和可能全高。你能用这些信息做什么?

我建议在'。'的2个子矩形上重复出现。 BUT ,现在不是选择中间列,而是选择中间行进行二进制搜索。

因此,N×M矩形的结果运行时间如下所示 T(N,M)= log(N)+ T(M / 2,N)* 2

请注意索引的更改,因为递归堆栈在检查列和行之间切换。最后的运行时间(我没有费心去解决递归)应该像T(M,N)= log(M)+ log(N)(它可能不完全是这样,但它会是相似的)。