Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 确定给定一组N个间隔是否覆盖了整个范围_Algorithm_Range - Fatal编程技术网

Algorithm 确定给定一组N个间隔是否覆盖了整个范围

Algorithm 确定给定一组N个间隔是否覆盖了整个范围,algorithm,range,Algorithm,Range,假设我有N个形式为[开始,结束]的区间。我需要找出这些间隔是否覆盖了整个范围 例如:如果我的区间为[4.5,5.765]和[5.8,10],区间为[5,10],则应报告为假,而对于相同的数据,如果区间为[6,9.99],则应报告为真 我需要1e-9的精度,间隔和范围将在[-10001000]内 这个问题在O(NlgN)时间内可以解决吗??其中N=间隔数。如果对所有间隔的起点和终点进行排序(O(N*logn)),则在O(N)过程中,您可以跟踪: 编号线上-1000和1000之间的当前位置,依次取

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

例如:如果我的区间为[4.5,5.765]和[5.8,10],区间为[5,10],则应报告为假,而对于相同的数据,如果区间为[6,9.99],则应报告为真

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


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

如果对所有间隔的起点和终点进行排序(
O(N*logn)
),则在
O(N)
过程中,您可以跟踪:

  • 编号线上
    -1000
    1000
    之间的当前位置,依次取任意间隔的每个起点/终点
  • 有多少间隔“当前”打开,即有多少间隔在编号线上的该点相交
如果在此过程中的任何一点,当前值在目标范围内,且当前间隔数为0,则目标范围不被间隔覆盖。如果在你到达目标射程的终点之前从未发生过这种情况,那么目标就被覆盖了

由于间隔已关闭,请记住在值为
r
的“起点”之前排序值为
r
的“终点”,以确保在间隔为
[0,1]
[1,2]
且目标为
[0,2]
的情况下返回“true”


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

虽然您已经得到了一些很好的答案,但我想我应该提供一些简单明了的东西

你没有告诉我们间隔是否可以重叠,所以我假设它们可以重叠。(否则,简单的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)
delta=1e-9
检查范围(范围、间隔[])
对于每个(intv间隔)
如果intv.start=range.end
返回真值
如果intv.endrange.end
持续
如果intv.startrange.start
range.start=interval.end
持续
如果intv.startrange.end
range.start=interval.end
持续
范围1=新范围(开始=范围.start,结束=intv.start-增量)
范围2=新范围(开始=intv.end+增量,结束=范围.end)
间隔=intv后的间隔
返回检查范围(范围1,间隔)和检查范围(范围2,间隔)

因为,对于数组或链表,可以将intv之后的
间隔保持在与原始
间隔[]
相同的内存空间中,这只会为递归迭代使用一些堆栈空间,仅此而已。至于计算复杂性,比我更好的人将不得不研究如何证明它,但我觉得它可能相当不错。

你可以做模糊排序。 最佳情况是
O(n)
和平均情况
O(n log n)
。这类似于快速排序。最佳情况发生在所有间隔中至少存在一个点时,即它们都重叠。一般来说,重叠越多,该算法优于任何其他排序算法


下面是对该算法的详细分析

间隔是否预先排序?您关心空间限制吗?不。间隔不是预先排序的。但它保证间隔将在[-10001000]范围内。很抱歉,现在我已经更新了。我有256MB的空间,但我认为这并不重要。您是否正在考虑存储每个值。呵呵!!所以理论上你可以创建一个位集,它是[-1000*1e9,1000*1e9],并在运行时屏蔽位。这在间隔数量上是线性的,但取决于总范围和每个间隔的范围。不幸的是,这会占用相当多的空间…我认为如果我有整数值,使用位掩码会更合适,或者精度会低得多。这占用了很多空间。有没有更好的算法。我听说过区间树,但我不确定它是否能完成这项任务。你可以假设NJust有趣的事情:排序后,我相信你可以使用不相交集来得到所有的闭合区间。