在给定一组N个间隔的情况下查找是否覆盖了整个范围

时间:2012-09-09 21:56:59

标签: algorithm range

假设我有[开始,结束]形式的N个区间。我需要弄清楚这些间隔是否覆盖了整个范围。

例如:如果我的间隔是[4.5,5.765]和[5.8,10]且间隔是[5,10],那么如果间隔为[6,9.99]则应该报告相同数据的假值报告确实。

我需要1e-9的精度。间隔和范围将在[-1000,1000]。

这个问题在O(NlgN)时间内是否可以解决?其中N =间隔数。

3 个答案:

答案 0 :(得分:2)

如果您对所有间隔(O(N * log N))的起点和终点进行排序,那么在O(N)段中您可以跟踪:

  • -10001000之间的数字行上的当前位置,该位置依次获取任何时间间隔的每个开始/结束点。
  • “当前”打开多少个间隔,即在数字线上此点处有多少个间隔相交。

如果在此过程中的任何一点,当前值都在目标范围内,并且当前的间隔数为0,则间隔不会覆盖目标范围。如果在到达目标范围的末尾之前从未发生过,那么目标就会被覆盖。

由于时间间隔已关闭,请务必在值为r的“起点”之前对值为r 的“终点”进行排序,以确保您返回如果时间间隔为[0,1][1,2]且目标为[0,2],则为“true”。

IEEE双精度对于+/- 1000范围内的粒度1e-9已足够,但请注意5.8无法在二进制浮点中精确表示的问题。因此,根据计算间隔的方式,计算或表示错误可能会引入微小的“间隙”。因此,您可能希望在开始之前进行某种舍入到最接近的十亿分之一,和/或使用基数为10而不是基数为2的相关值表示。

答案 1 :(得分:1)

虽然你已经得到了一些好的答案,但我认为我会做出简单而简单的贡献。

你没有告诉我们间隔是否可以重叠,所以我会假设他们可以。 (否则,简单的O(N)搜索过程将告诉您您的范围是否在其中一个区间内。)

如果多个范围的间隔设置保持不变,最好的办法是根据起点对预设间隔进行预先排序。 (这通常是O(N logN)操作,但您只需要执行一次)。然后,你可以这样做:

checkRange(range, intervals[])
    for each ( intv in intervals )
        if intv.start > range.start
            return false
        if intv.end >= range.end
            return true
        if intv.end > range.start
            range.start = interval.end

    return false

这只是一次O(N)传球。

如果每个范围的间隔集可以更改,那么以下递归算法可能会或者可能不会比每次排序间隔更好:

delta = 1e-9

checkRange(range, intervals[])
    for each ( intv in intervals )
        if intv.start <= range.start and intv.end >= range.end
            return true
        if intv.end < range.start or intv.start > range.end
            continue
        if intv.start < range.start and intv.end > range.start
            range.start = interval.end
            continue
        if intv.start < range.end and intv.end > range.end
            range.start = interval.end
            continue
        range1 = new range(start = range.start, end = intv.start - delta)
        range2 = new range(start = intv.end + delta, end = range.end)
        intervals = intervals after intv
        return checkRange(range1, intervals) and checkRange(range2, intervals)

因为,对于数组或链表,您可以将intervals after intv保留在与原始intervals[]相同的内存空间中,这只是使用一些堆栈空间进行递归迭代而不是更多。至于计算复杂性,比我更好的人将不得不考虑证明它的内容,但我觉得它可能相当不错。

答案 2 :(得分:0)

您可以进行模糊排序。 最好的情况是O(n)和平均情况O(n log n)。这类似于快速排序。当所有间隔中存在至少一个点时,即最佳情况发生,即它们全部重叠。通常,重叠越多,算法与任何其他排序算法相比就越好。

以下是此算法的详细分析。 http://web.media.mit.edu/~dlanman/courses/cs157/HW3.pdf