繁体   English   中英

在部分排序的数组中查找元素

[英]Finding an element in partially sorted array

我有以下面试问题。

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

这是我对此的看法:

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

从评论中

总共不是 O(n * log n) 吗? 他必须解析每个二分搜索到达的每一行,因此线性搜索的数量乘以他平均必须扫描的行数。 – Martin Matysiak 5 分钟前。

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

假设您正在搜索解析的每一行,您的解决方案确实需要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)

这是一个简单的实现 - 因为无论如何我们需要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);
            }
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM