给出以下数据:
[4]
[5, 8]
[9, 12, 20]
[10, 15, 23, 28]
[14, 19, 31, 36, 48]
[15, 22, 34, 41, 53, 60]
[19, 26, 42, 49, 65, 72, 88]
[20, 29, 45, 54, 70, 79, 95, 104]
[24, 33, 53, 62, 82, 91, 111, 120, 140]
[25, 36, 56, 67, 87, 98, 118, 129, 149, 160]
[29, 40, 64, 75, 99, 110, 134, 145, 169, 180, 204]
[30, 43, 67, 80, 104, 117, 141, 154, 178, 191, 215, 228]
[34, 47, 75, 88, 116, 129, 157, 170, 198, 211, 239, 252, 280]
[35, 50, 78, 93, 121, 136, 164, 179, 207, 222, 250, 265, 293, 308]
[Etc.]
对于找到给定数字,具有最佳时间复杂度的最佳搜索算法是什么?
其他信息:
假设我们要查找数字26:
由于要进行排序,这意味着我们可以消除右侧的前3行和其余的列。
由于顺序,这也意味着我们可以忽略row = 11之后的每一行。
结果如下:
[10, 15, 23]
[14, 19, 31]
[15, 22, 34]
[19, 26, 42]
[20, 29, 45]
[24, 33, 53]
[25, 36, 56]
[29, 40, 64]
我当前的算法的时间复杂度为O(x log(y)),其中x是列数,y是每列二进制搜索算法的大小。
我正在寻找更快的东西,因为我正在处理大量数据。
当前我在每一列上都使用BST,但是我也可以在行上使用BST吗?也许达到O(log(x)log(y))?
答案 0 :(得分:2)
可以在O(x)
让我们调用我们试图找到n的元素
从左下方的元素开始。
对于我们搜索的每个元素(我们称其为e):
如果e == n:我们找到了
如果e
正当化:
e左侧的所有元素(包括e所在的列)均小于e。这些元素不能== n并且可以消除。
正当化:
e下面的所有元素都大于e,可以删除。小于e左边的e的值呢?那不是== n吗?否。要使e向右移动并向左移动值,这些值将在第2步中被消除
重复直到找到n个或索引超出范围,在这种情况下,这样的元素不存在。
时间复杂度:
最坏的情况是如果元素不在数组中,并且索引超出范围。这发生在主对角线上,到右的总距离以及长对角线上任何元素的总距离总和为x
。
答案 1 :(得分:1)
您可以在修整后的数组的左下角找到第一行的二进制搜索,在右上角找到二进制搜索的每一行的最后一列。
从那里,问题退化为How do I search for a number in a 2d array sorted left to right and top to bottom?,该问题已在链接的问题中进行了充分研究。最佳算法取决于结果的形状。