找出一个数字所属的区间

时间:2018-01-24 04:59:10

标签: java scala data-structures

我有一大堆间隔(开始,结束)是连续的和不重叠的。给定一个数字,我想知道它属于哪个区间。

我目前正在编写基于二进制搜索的解决方案 - 我想知道使用标准库数据结构(如TreeMap或TreeSet)是否可行。

2 个答案:

答案 0 :(得分:0)

如果我理解你的需要,你有一个范围列表,如(1,5),(6,10),(11,18)等等。当给出类似4的输入时,您希望返回包含此输入的范围。

这是Scala中的一个版本:

scala> val input = List((1,5), (6,10),(11,18))
input: List[(Int, Int)] = List((1,5), (6,10), (11,18))

scala> input.filter(elem => 4 <= elem._2 && 4 >= elem._1)
res1: List[(Int, Int)] = List((1,5))

您可以通过将其解压缩到方法并传递输入参数来扩展它。

您可以根据用例替换所需的集合类型。看看这里的集合性能特征:

http://docs.scala-lang.org/overviews/collections/performance-characteristics.html

如果要使用TreeSet,可以执行以下操作:

scala> val in = TreeSet((1,5),(6,10),(11,15))
in: scala.collection.immutable.TreeSet[(Int, Int)] = TreeSet((1,5), (6,10))

scala> in.filter(elem => 4 <= elem._2 && 4 >= elem._1)
res2: scala.collection.immutable.TreeSet[(Int, Int)] = TreeSet((1,5))

答案 1 :(得分:0)

是的,可以使用标准Java或Scala的TreeMap(下面是RB树)。

代码:

import scala.collection.immutable.TreeMap

val ranges = TreeMap((1, 5), (8, 10), (11, 18))

def contains(intervals: TreeMap[Int, Int])(el: Int) =
  intervals.to(el).lastOption.exists(_._2 >= el)

(-1 to 20).foreach { i =>
  println(s"$i ${contains(ranges)(i)}")
}

打印:

-1 false
0 false
1 true
2 true
3 true
4 true
5 true
6 false
7 false
8 true
9 true
10 true
11 true
12 true
13 true
14 true
15 true
16 true
17 true
18 true
19 false
20 false

这个想法是使用to方法,该方法返回一个小于或等于给定元素的键的映射投影。如果地图包含与给定点相交的间隔,则此间隔将是投影中的最大键。因此,唯一剩下的就是检查该区间的值(右边界)是否大于相关元素。

tolastOption方法都适用于O(log n)的RB树。

此实现假设范围包含范围,但应该很容易修改此代码以获得独占范围。