【问题标题】:Is there a faster way to search whether a value is within an interval given a list of intervals?有没有更快的方法来搜索一个值是否在给定区间列表的区间内?
【发布时间】:2019-01-17 01:15:21
【问题描述】:

作为我的代码的一部分,我遇到了以下问题: 我有以下列表:

    intervals = [(1,3), (5,12), (16,20)]
    labels = [[1,2],[1],[2,3]]

第一个是排序的、不重叠的区间列表,第二个是相应区间的“允许”标签。例如,在区间(1,3) 中允许使用标签 1 和 2。此外,区间的形式为 [a,b)。

我想找到一个元组(t, l)

  1. t 在列表区间的区间内。
  2. l 在该时间间隔内是允许的。

我能想到的方法是将区间列表分成低点和高点:

    lows = np.array([1,5,16])
    highs = np.array([3,12,20])
    find_indx = np.where(lows >= t)
    if len(find_indx[0]) > 0:
         indx = find_indx[0][0]
         if t < highs[low_indx] and l in labels[low_indx]:
              return 'Yes'
    return 'No'

对于这个问题是否有更快/更清洁的方法?使用二分查找比使用内置 python 函数更快吗?

【问题讨论】:

  • 对,二分查找是log(N),你可以在这里使用
  • Pandas 有二分查找功能。我的主要问题是是否有重叠的间隔或者它们是否不重叠
  • @Primusa:虽然只有在intervals 更大时才会有所不同;即使使用 C 加速 bisect 模块,因为线性扫描将赢得较小的 intervals
  • 我怀疑您可以通过设置dict 来显着加快这一速度(对于足够大的intervals/labels 进行测试),其中键是labels,值是(已排序)该label 允许的范围。这意味着代替查找合法间隔(在您的代码中线性,登录更好的代码),然后线性扫描具有所需标签的那些,您可以在dict 中查找O(1) 查找范围,然后线性(或对数)搜索已修剪的范围集。
  • @Primusa 间隔不重叠。

标签: python search data-structures


【解决方案1】:

可以在起始区间上实现二分查找,将每次查找的时间复杂度降低到log(N)。例如,让

label = [10,11]
intervals = [(1,3), (5,12), (16,20)]

由于区间不重叠,我们需要找到第一个区间开始小于或等于标签的开始。

    int val = 10;
    int arr[] = {1,5,16};

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

    while(high>=low)
    {
        int mid = low + (high-low)/2;
        if(arr[mid] == val)
            return arr[mid];
        else if(high == arr.length-1 && arr[mid]<val)
            return arr[high];
        else if(low == 0 && arr[mid]>val)
            return arr[low];
        else if(arr[mid]>val)
            high = mid-1;
        else
            low = mid+1;
    }

    System.out.println(arr[low]);

这里的输出是 5。现在我们可以很容易地检查给定的标签是否属于这个区间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-09
    • 2014-09-23
    • 1970-01-01
    • 2014-12-17
    • 2017-02-14
    • 2013-10-17
    • 2020-02-13
    • 1970-01-01
    相关资源
    最近更新 更多