当前位置: 首页 > 知识库问答 >
问题:

获取排序数组中在log(n)时间内落在某个范围内的元素数

郏兴贤
2023-03-14

假设我有一个由以下类组成的数组,按y升序排序:

public class Obj {
    public int x;
    public int y;
}

如何在log(N)time中给定的最小值和最大值范围内找到数组中y值的Obj项目数?

我曾想过使用二进制搜索和减法来查找最小和最大元素的位置,但这不是2 log(n),因为它搜索了两次吗?

public static int getNumberOfItems(Obj[] a, int min, int max) {

共有3个答案

邓开济
2023-03-14

这个问题与这里相同,我在这里给出了O(logn)实现。

这个想法是通过范围二分搜索下界和上限。对于您的示例,所有值都在谈论y值。

>

int binarySearchForLeftRange(int a[], int length, int left_range)
{
    if (a[length-1] < left_range)
        return -1;

    int low = 0;
    int high = length-1;

    while (low<=high)
    {
        int mid = low+((high-low)/2);

        if(a[mid] >= left_range)
            high = mid-1;
        else //if(a[mid]<i)
            low = mid+1;
    }

    return high+1;
}

对于上限(右范围),您可以调用以下函数来获取排序数组中值小于或等于它的索引,否则为-1。

int binarySearchForRightRange(int a[], int length, int right_range)
{
    if (a[0] > right_range)
        return -1;

    int low = 0;
    int high = length-1;

    while (low<=high)
    {
        int mid = low+((high-low)/2);

        if(a[mid] > right_range)
            high = mid-1;
        else //if(a[mid]<i)
            low = mid+1;
    }

    return low-1;
}

最后,如果您想得到这个范围内有多少个元素,可以很容易地根据上述两个函数的返回值来确定。

int index_left = binarySearchForLeftRange(a, length, left_range);
int index_right = binarySearchForRightRange(a, length, right_range);

if (index_left==-1 || index_right==-1 || index_left>index_right)
    count = 0;
else
    count = index_right-index_left+1;

测试:(重复)

    int a[] = {1,2,4,4,5,8,12,15,15,23,54};
    int length = sizeof(arr)/sizeof(arr[0]);

    int left_range = 4;
    int right_range = 15;
    int index_left = binarySearchForLeftRange(a, length, left_range); // will be 2
    int index_right = binarySearchForRightRange(a, length, right_range); // will be 8

    int count; // will be 7
    if (index_left==-1 || index_right==-1 || index_left>index_right)
        count = 0;
    else
        count = index_right-index_left+1;
东方建修
2023-03-14

bin search对于这种方法来说很好,O(log N)表示c*log N。所以bin search很好,但您可以通过在范围内搜索omg(minFoundIndex,N)来优化maxIndex searchimg的bin search调用

江航
2023-03-14

当您被要求在log(n)时间内做某事时,这通常意味着O(log(n))

如果这里是这种情况,值得注意的是O(2 log(n))==O(log(n)),即两者是同样的事情。

有关大oh符号的更多背景信息,请参阅维基百科页面。

 类似资料:
  • 使用Redisson中的rxjava2客户机,试图获取排序集中得分范围内的元素计数时,我得到了一个ClassCastException。 代码段: 你知道如何解决这个问题吗?

  • 我遇到了一个面试问题,要求候选人计算数组中具有相同数字的所有数字。例如: 计算所有与int input=394 int[]arr={1,14,101,349,439,745,934}共享相同数字的数字 该函数将返回3,因为439, 934, 349共享相同的数字。问题是如何在O(log n)时间内解决这个问题?我对Big O概念还是个新手,除了O(n)和O(n^2)...我很难理解如何归档O(lo

  • 问题内容: 因此,我试图生成的是特定时间范围内的所有小时。 因此,鉴于范围从上午11点到下午2:00,我将得到: 我试图避免必须在商店每隔特定的小时存储一次,而只存储范围(我需要将小时数与其他时间进行比较) 谢谢 问题答案: 如果您有数字表(如果没有,请单击链接以创建一个表)… 如果这是专门的,则可以创建仅包含24个值的小时表。

  • 本文向大家介绍在指定范围内填充Java float数组中的元素,包括了在指定范围内填充Java float数组中的元素的使用技巧和注意事项,需要的朋友参考一下 可以使用java.util.Arrays.fill()方法将元素填充到指定范围内的Java float数组中。此方法将指定范围内所需的float值分配给Java中的float数组。 Arrays.fill()方法所需的参数是数组名称,要填充

  • 本文向大家介绍在Python中删除范围内的元素,包括了在Python中删除范围内的元素的使用技巧和注意事项,需要的朋友参考一下 通过使用元素的索引和del函数,可以直接从python删除单个元素。但是在某些情况下,我们需要删除一组索引的元素。本文探讨了仅删除索引列表中指定的列表中那些元素的方法。 使用排序和删除 在这种方法中,我们创建一个包含必须删除的索引值的列表。我们对它们进行排序和反转以保留列

  • 问题内容: 做到这一点的最佳方法是什么? 问题答案: 使用 array_slice() 这是PHP手册中的一个示例:array_slice 只有一个小问题 如果数组索引对您有意义,请记住这将重置并重新排列 数字 数组索引。您需要设置标志来避免这种情况。(第4个参数,自5.0.2起可用)。 例: 输出: