[英]Inserting an interval in a sorted list of disjoint intervals
I have a sorted list of disjoint intervals and an interval, eg [(1, 5), (10, 15), (20, 25)] and (12, 27). 我有一个不相交的间隔和间隔的排序列表,例如[[(1,5),(10,15),(20,25)]和(12,27)。 So, (12,27) is the interval I want to merge them into a sorted list of disjoint intervals: [(1, 5), (10, 27)]. 因此,(12,27)是我想要将它们合并为不相交间隔的排序列表的间隔:[(1,5),(10,27)]。
pseudo: 伪:
list = ...
u = (12,27)
i = 0
newlist = []
while (max(list[i]) < min(u)) //add all intervals before intersection
newlist.add(list[i++])
mini = i
while (min(list[i]) < max(u)) // skip all intersecting intervals
i++
maxi = i
newlist.add((min(list[mini],u),max(list[maxi],u)) // add the new interval
while (i < list.length) // add remaining intervals
newlist.add(list[i++])
return newlist
Here is my non-idiomatic scala solution full of vars. 这是我的充满变量的非惯用的scala解决方案。 The solution looks longer than it should be because I have poor implementations of append and insert on lists which only support the prepend operation. 该解决方案看起来比应有的更长的时间,因为我在列表上执行append和insert的实现效果较差,这些列表仅支持prepend操作。
The algo is as follows: 算法如下:
Here is the code: 这是代码:
object trial {
val intervals1 = List((1, 2), (4, 6), (7, 8), (16, 17)))
val intervals2 = List((1, 5), (10, 15), (20, 25)
val newInterval1 = (11, 12)
val newInterval2 = (12, 27)
// Interval algo test.
val result1 = Merge(intervals1, newInterval1) // result1 : List((1,2), (4,6), (7,8), (11,12), (16,17))
val result2 = Merge(intervals2, newInterval2) // result2 : List[(Int, Int)] = List((1,5), (10,27))
}
object Merge{
def append[T](list: List[T], el: T): List[T] = {
(el :: list.reverse).reverse
}
def insert[T](list: List[T], pos: Int, elem: T): List[T] = {
var newList = List.empty[T]
val reversePos = list.length - pos
list.reverse.zipWithIndex foreach {
case(el, i) if i == reversePos => {
newList = elem :: newList
newList = el :: newList
}
case (el, i) => newList = el :: newList
}
newList
}
def apply(list: List[(Int, Int)], interval: (Int, Int)): List[(Int, Int)] = {
val (min, max) = interval
var newList = List.empty[(Int, Int)]
// Store potentially overlapping stuff.
var overlap = List.empty[(Int, Int)]
// Maintain the position to begin merge.
var posInsert = 0
list.zipWithIndex foreach { case(intervalz, i) =>
if (intervalz._2 < min) {
// Does not overlap but an insert will be after the highest of these.
posInsert = i
newList = append(newList, intervalz)
} else if (intervalz._1 > max) {
// Does not overlap.
newList = append(newList, intervalz)
} else overlap = append(overlap, intervalz)
}
if (overlap isEmpty) {
if (posInsert == 0) newList = interval :: newList
else newList = insert(newList, posInsert + 1, interval)
} else {
// Start of new interval is the lower of the first overlap's start or the interval's start.
val startOfInterval = Math.min(overlap.head._1, min)
// Enf of interval is higher of last overlap's end or interval's end.
val endOfInterval = Math.max(overlap.head._2, max)
// Insert the merged interval after the highest interval smaller than the start of the new internval.
if (posInsert == 0) newList = (startOfInterval, endOfInterval) :: newList
else newList = insert(newList, posInsert + 1, (startOfInterval, endOfInterval))
}
newList
}
}
It passes the tests mentioned here and is O(N). 它通过了此处提到的测试,并且为O(N)。
EDIT. 编辑。 The algo version of it: 它的算法版本:
intervals = [....]
newInterval = (12, 27)
newList = []
overlappingList = []
posInsert = 0
i = 0
while (i < intervals.size)
if (intervals[i].max < newInterval.min)
posInsert = i
append(newList, intervals[i])
else if (intervals[i].min > newInterval.max)
append(newList, intervals[i])
else
append(overlappingList, intervals[i])
i++
if (overlap isEmpty)
if (posInsert == 0) prepend(newList, newInterval)
else insert(newList, posInsert + 1, newInterval)
else
start = Min(overlappingList[i].min, newInterval.min)
end = Max(overlappingList[i].max, newInterval.max)
if (posInsert == 0) prepend(newList, newInterval)
else insert(newList, posInsert + 1, new Interval(start, end))
return newList
You can model your problem with graph, in fact your intervals are nodes and they are connected to each other if they have common parts (eg (12,27) is connected to (15,20)) now first you should find connected components, then in each connected component find min value of start (eg 10) and max value of end (eg 25). 您可以使用图形来建模问题,实际上,您的间隔是节点,并且如果它们具有相同的部分(例如(12,27)连接到(15,20)),则它们是相互连接的。现在,您首先应该找到连接的组件,然后在每个连接的组件中找到开始的最小值(例如10)和结束的最大值(例如25)。 It's good to see Interval Graphs . 看到间隔图很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.