【问题标题】:Finding an element in partially sorted array在部分排序的数组中查找元素
【发布时间】:2011-06-04 09:19:41
【问题描述】:

我有以下面试问题。

有一个 nxn 元素的数组。该数组是部分排序的,即i 行中的最大元素小于i+1 行中的最小元素。 如何找到复杂度为 O(n) 的给定元素

这是我的看法:

您应该转到第 n/2 行。然后开始比较,例如您搜索 100,您看到的第一个数字是 110,所以您知道它在这一行或上面的行中,现在您转到 n/4 等等开。

来自cmets

一共不是 O(n * log n) 吗?他有 解析他的每一行 达到每个二分搜索,因此 线性搜索的次数是 乘以他的行数 将不得不平均扫描。 – 马丁 Matysiak 5 分钟前。

我不确定这是一个正确的解决方案。有人有更好的吗

【问题讨论】:

  • 听起来对我来说是正确的。 O(log n) 减少到两个候选行,O(n) 找到这些行之一中的元素。总共是 O(n)。
  • 在排序数组中你不能比二分搜索做得更好,在未排序数组中你不能比线性搜索做得更好,所以这对我来说似乎是最优的。
  • 是正确的。二分搜索,然后是线性搜索。由于未排序的行,你不会比 O(n) 更好。
  • 一共不是 O(n * log n) 吗?他必须解析每次二分搜索到达的每一行,因此线性搜索的数量乘以他必须扫描的平均行数。
  • 我认为 Martin 是对的有没有人有想法这样做 O(n)?

标签: c++ arrays algorithm


【解决方案1】:

假设您正在搜索解析的每一行,您的解决方案确实需要O(n log n)。如果不搜索每一行,则无法准确执行二进制步骤。

O(n)解决方案:

选择n/2 行,而不是搜索整行,我们只取上一行的第一个元素和下一行的第一个元素。 O(1).
我们知道n/2 行的所有元素都必须在这些选定的值之间(这是关键观察)。如果我们的目标值在区间内,则搜索所有三行 (3*O(n) = O(n))。

如果我们的值超出此范围,则继续以二分查找方式,如果我们的值小于该范围,则选择n/4,如果值更大,则选择3n/4行,并再次与相邻的行。

找到正确的 3 行块将花费 O(1) * O(log n),找到元素将花费 O(n)

总共O(log n) + O(n) = O(n)

【讨论】:

  • 实际上通过搜索行并与行的第一个(或任何)值进行比较)您将可能的行限制为 2 而不是 3。
  • @dcn,不正确。 { 1 2 3 ; 4 5 6 ; 8 7 9 } 搜索 {2,5,7} 中的任何一个都会得出目标确实在 [1,8] 范围内,但还没有找到我需要搜索所有 3 行的值,如果我不这样做,我不会找到一个的值。
  • 没有。搜索“2”。与更大的“5”相比 -> 只能在第 1 行和第 2 行。同样的论点也适用于搜索 5 和 7。
  • 我的错。我以为您是在与连续行中的元素进行比较,但再读一遍,prev 和 next 不应该是邻居。
  • 您当然可以将其减少到 2 行,如下所示:通过 binsearch,您可以找到行的最小索引 maxrow ,这样 的第一个元素maxrow 比您要查找的元素大。那么只有 maxrowmaxrow-1 是候选者
【解决方案2】:

这是一个简单的实现 - 因为无论如何我们需要 O(n) 来在一行中查找一个元素,所以我省略了 bin-search...

void search(int n[][], int el) {
    int minrow = 0, maxrow;
    while (minrow < n.length && el >= n[minrow][0])
        ++minrow;
    minrow = Math.max(0, minrow - 1);
    maxrow = Math.min(n.length - 1, minrow + 1);
    for (int row = minrow; row <= maxrow; ++row) {
        for (int col = 0; col < n[row].length; ++col) {
            if (n[row][col] == el) {
                System.out.printf("found at %d,%d\n", row, col);
            }
        }
    }
}

【讨论】:

  • 起初我很困惑为什么你使用线性搜索来遍历行,但后来一分钱掉了...... O(n) + O(n) = O(log n) + O (n) = O(n),所以如果你不需要,为什么要花哨! :) (当然,如果它是一个 m*n 矩阵,那么为了获得最优性,你毕竟需要二进制搜索......)
  • @dcn - 你能解释一下minrow和maxrow计算背后的逻辑吗?
猜你喜欢
  • 2015-03-17
  • 2012-08-31
  • 2021-09-28
  • 2014-01-07
  • 2020-11-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-07
  • 1970-01-01
相关资源
最近更新 更多