我有一个排序的不连续区间列表和一个区间,例如, [(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++])
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
该算法不会工作。考虑列表[(1,2),(4,6),(7,8),(16,17)]和插入(11,12)。你的算法会创建间隔(7,12),但这是错误的,因为间隔(9,10)并不意味着在那里!那么说,好的尝试 – TimeToCodeTheRoad 2011-12-19 19:47:52
只需要处理特殊情况下时,微型== maxi,一般的想法保持不变。 – yurib 2011-12-19 20:14:48
我不认为这是非常有效的。插入位置的二进制搜索是按顺序进行的。 – maasha 2012-04-18 13:47:31
您可以用图形您的问题模式,其实你的间隔为节点,它们相互连接,如果他们有共同部分(例如,(12,27)连接到(现在首先应该找到连接的组件,然后在每个连接组件中找到最小值开始(例如10)和最大值结束(例如25)。很高兴看到Interval Graphs。
这是我的非惯用斯卡拉解决方案充满变数。该解决方案看起来比它应该是更长的时间,因为我有穷人的实施append和插入列表只支持prepend操作。
的ALGO如下:
- 扫描到间隔列表分为两个列表那些不使用新的时间间隔和那些做重叠。非重叠间隔是在新间隔之后或完全在新间隔之前开始的间隔。另外,如果我们要插入一个新的时间间隔,它会在最低的时间间隔之后。在这个阶段,我们有一个重叠间隔列表和一个非重叠列表。
- 如果没有重叠,则新的间隔要么早于所有给定的间隔,要么在所有的间隔之后,或者在两个间隔之间(仍然没有重叠)。
- 如果存在重叠,则将重叠区间与新区间合并。重叠区间的开始是min(新区间的开始,最小重叠区间的开始)。我们可以类似地计算结束。现在将重叠间隔插入之前计算的位置。
下面是代码:
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
}
}
它通过这里提到的测试和为O(N)。
编辑。它的算法版本:
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
- 1. 插入一个已排序列表
- 2. 在已排序的MS Access查询中查找连续区域
- 3. Mysql中连续行之间的区别
- 4. 插入排序中的比较和交换之间的区别
- 5. 将区间插入不相交的区间集合
- 6. Prolog在区间内连续绑定
- 7. 在已排序的链接列表中插入节点的时间复杂度
- 8. 列表和序列之间的区别
- 9. 概率区间和图表排序?
- 10. 已排序的插入链接列表
- 11. 插入已排序的链接列表
- 12. 在熊猫中插入一个时间序列到另一个时间序列
- 13. 时区的时间序列
- 14. 我们可以在单个区间内插入多个表吗?
- 15. 如何在不同的时区连续显示当前时间?
- 16. 排序链接列表的方法之间的区别C++
- 17. 在'时间系列熊猫蟒'中连续插入'n/a'
- 18. 在Python中的列表,序列和切片之间的区别?
- 19. 插入列表的中间
- 20. 在区间列表中快速查找
- 21. 如何用elisp在缓冲区中插入一个lenghthier列表?
- 22. 区间链接列表
- 23. 列表,排序列表和数组列表之间有什么区别? (c#)
- 24. 搜索跨区域不连续区域
- 25. ClosedXML中的中心和中间连续对齐之间的区别?
- 26. 在内核空间中创建连续区域
- 27. Python中列表之间的区别
- 28. 在R中有不连续轴的绘图时间序列
- 29. updated_at列在插入期间已更改
- 30. 插入到每行或每个表只有一个之间的区别
它与将整数插入排序整数列表中没有区别。它们都可以以相同的方式相互比较。 – hugomg 2011-12-19 17:00:03