Algorithm 在不相交区间的排序列表中插入区间
我有一个不相交区间的排序列表和一个区间,例如[(1,5),(10,15),(20,25)]和(12,27)。所以,(12,27)是间隔 我想把它们合并成一个不相交区间的排序列表:[(1,5)、(10,27)] 伪:Algorithm 在不相交区间的排序列表中插入区间,algorithm,Algorithm,我有一个不相交区间的排序列表和一个区间,例如[(1,5),(10,15),(20,25)]和(12,27)。所以,(12,27)是间隔 我想把它们合并成一个不相交区间的排序列表:[(1,5)、(10,27)] 伪: list = ... u = (12,27) i = 0 newlist = [] while (max(list[i]) < min(u)) //add all intervals before intersection newlist.add(list[i++])
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
list=。。。
u=(12,27)
i=0
新列表=[]
while(max(list[i])
伪:
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
list=。。。
u=(12,27)
i=0
新列表=[]
while(max(list[i])
您可以使用图形对问题进行建模,事实上,您的间隔是节点,如果它们有公共部分(例如(12,27)连接到(15,20)),则它们彼此连接。现在,您应该首先查找连接的组件,然后在每个连接的组件中查找开始的最小值(例如10)和最大值end(例如25)。很高兴看到。您可以用图形建模您的问题,事实上,您的间隔是节点,如果它们有公共部分(例如(12,27)连接到(15,20)),则它们相互连接现在,您应该首先找到连接的组件,然后在每个连接的组件中找到开始的最小值(例如10)和结束的最大值(例如25)。很高兴看到。这是我的非惯用scala解决方案,其中充满了变量。该解决方案看起来比它应该的要长,因为我的append和insert-on-List的实现很差,只支持prepend操作
算法如下:
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
}
}
目标审判{
val intervals1=列表((1,2)、(4,6)、(7,8)、(16,17)))
val intervals2=列表((1,5)、(10,15)、(20,25)
val newInterval1=(11,12)
val newInterval2=(12,27)
//间隔算法测试。
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))
}
对象合并{
def append[T](列表:列表[T],el:T):列表[T]={
(el::list.reverse)。反向
}
def insert[T](列表:列表[T],位置:Int,元素:T):列表[T]={
var newList=List.empty[T]
val reversePos=list.length-pos
list.reverse.zipWithIndex foreach{
如果i==reversePos=>{
newList=elem::newList
newList=el::newList
}
案例(el,i)=>newList=el::newList
}
新名单
}
定义应用(列表:列表[(Int,Int)],间隔:(Int,Int)):列表[(Int,Int)]={
val(最小值,最大值)=间隔
var newList=List.empty[(Int,Int)]
//存储可能重叠的内容。
var overlap=List.empty[(Int,Int)]
//保持开始合并的位置。
var posInsert=0
list.zipWithIndex foreach{case(intervalz,i)=>
如果(间隔2<分钟){
//不重叠,但插入将位于其中的最高位置之后。
posInsert=i
newList=append(newList,intervalz)
}否则如果(间隔时间>最大值){
//不重叠。
newList=append(newList,intervalz)
}else重叠=附加(重叠,间隔)
}
如果(重叠为空){
如果(posInsert==0)newList=interval::newList
else newList=insert(newList,posInsert+1,interval)
}否则{
//新间隔的起点是第一个重叠的起点或间隔的起点中的较低者。
val startOfInterval=Math.min(重叠头1,min)
//区间的Enf高于最后一个重叠的终点或区间的终点。
val endOfInterval=数学最大值(重叠头2,最大值)
//在小于新interval开头的最高间隔之后插入合并间隔。
如果(posInsert==0)newList=(startOfInterval,endOfInterval)::newList
else newList=insert(newList,posInsert+1,(startOfInterval,endOfInterval))
}
新名单
}
}
它通过了这里提到的测试,是O(N)
编辑。它的algo版本:
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
interval=[…]
新间隔=(12,27)
新列表=[]
重叠列表=[]
posInsert=0
i=0
while(inewInterval.max)
追加(新列表,间隔[i])
其他的
追加(重叠列表,间隔[i])
我++
如果(重叠为空)
if(posInsert==0)前置(newList,newInterval)
else插入(newList,posInsert+1,newInterval)
其他的
开始=最小值(重叠列表