【问题标题】:Search algorithm with best Time Complexity [duplicate]具有最佳时间复杂度的搜索算法
【发布时间】:2019-05-30 11:51:16
【问题描述】:

给定以下数据:

[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))?

【问题讨论】:

    标签: algorithm search time time-complexity


    【解决方案1】:

    可以在O(x)完成

    让我们将要查找的元素称为 n

    从左下角的元素开始。

    对于我们搜索的每个元素(我们称之为 e):

    1. 如果 e == n:我们找到了

    2. 如果 e

    理由:

    e 左边的所有元素,包括 e 所在的列,都小于 e。那些元素不能 == n 并且可以被消除。

    1. 如果 e > n:向上移动

    理由:

    所有低于e的元素都大于e,可以排除。那么 e 左边小于 e 的值呢?那些不能是== n吗?不。对于 e 向右移动并在其左侧有值,这些值将在第 2 步中已被消除

    重复直到找到 n 或索引超出范围,在这种情况下这样的元素不存在。

    时间复杂度:

    最坏的情况是如果元素不在数组中并且我们的索引超出范围。这发生在主对角线上,向右的总距离和到长对角线上任何元素的总距离总和为x

    【讨论】:

    • 但这更慢?
    • 不是,你失去了log y 因素,这是O(x)。在最初的编辑中是O(N),N 表示行数而不是总元素数。
    • 我认为是O(x + y)。最坏的情况是检查每一行和每一列中的值。
    • 我很确定这会慢一些,我认为你的 O(x) 是 x = mn 其中 m = 行和 n = 列。想一想,你从左下角开始,如果值在右上角,则需要列数和行数才能到达那里,ergo x = mn 比 O(m log (n)) ?
    • @GeorgiGerganov 确实如此,但最坏的情况仍然是O(x),也就是说你每次都必须向上和向右移动一次
    【解决方案2】:

    您可以通过对第一列的二进制搜索找到修剪后数组的左下角,通过对每行最后一列的二进制搜索找到右上角。

    从那里,问题退化为How do I search for a number in a 2d array sorted left to right and top to bottom?,这在链接问题中得到了充分研究。最佳算法取决于结果的形状。

    【讨论】:

    • +1,虽然我认为你实际上最好跳过“你可以通过对第一列的二进制搜索找到修剪后的数组的左下角”部分:找到右上角就足够了要将这个问题减少到您链接到的问题,因此您应该使用那里的策略,而不是尝试以可能不是最佳的方式预先缩小问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-23
    • 2020-08-09
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    • 2011-07-25
    相关资源
    最近更新 更多