今天我在接受采访时被问到以下问题:
给定一个n乘n的整数数组,它不包含从左到右以及从上到下增加的重复项和值,提供一种算法来检查给定值是否在数组中。
我提供的答案类似于此主题中的答案:
Algorithm: efficient way to search an integer in a two dimensional integer array?
该解决方案是O(2n),我认为这是最佳解决方案。
然而,采访者告诉我,有可能在子线性时间内解决这个问题。我已经绞尽脑汁想要如何做到这一点,但我什么都没有。
子线性解是可能的,还是最优解?
答案 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)(它可能不完全是这样,但它会是相似的)。