假设我们希望跟踪一组间隔中的最大重叠点 - 数据库中具有最大间隔数的点与其重叠。
一个。表明总会有一个最大重叠点,这是一个段的端点。
湾设计一个有效支持INTERVAL-INSERT,INTERVAL-DELETE和FIND-POM操作的数据结构,它返回一个最大重叠点。 (提示:保留所有端点的红黑树。将值+1与每个左端点相关联,并将值-1与每个右端点相关联。使用一些额外信息扩充树的每个节点以维护最大重叠点。)
这个问题出现在算法简介一书中。但我不知道如何解决第二个问题。如果一个更大的头脑有一个优雅的解决方案,请与我分享你的想法!感谢。
答案 0 :(得分:3)
报价:http://ripcrixalis.blog.com/2011/02/08/clrs-chapter-14/
保留所有端点的RB树。 我们逐个插入端点作为从左到右扫描的扫描线。对于每个左端点e,将值p [e] = +1相关联(将重叠增加1)。每个右端点e关联一个值p [e] = -1(将重叠减少1)。 当多个端点具有相同的值时,在插入具有该值的任何右端点之前,插入具有该值的所有左端点。
这是一些直觉。设e1,e2,.... 。 。 ,en是与我们的间隔对应的已排序的端点序列。令s(i,j)表示对于1≤i≤j≤n的和p [ei] + p [ei + 1] +···+ p [ej]。 我们希望找到一个最大化s(1,i)。 每个节点x存储三个新属性。 我们存储v [x] = s(l [x],r [x]),即x子树中所有节点的值之和。 我们还存储m [x],即由任意i得到的表达式s(l [x],i)得到的最大值。 我们将o [x]存储为m [x]达到其最大值的i的值。对于哨兵,我们定义v [nil [T]] = m [nil [T]] = 0。
我们可以自下而上的方式计算这些属性,以满足定理14.1的要求:
v[x] = v[left[x]] + p[x] + v[right[x]] ,
m[x] = max{
m[left[x]] (max is in x’s left subtree),
v[left[x]] + p[x] (max is at x),
v[left[x]] + p[x] + m[right[x]] (max is in x’s right subtree). }
一旦我们理解了如何计算m [x],就可以直接从x及其两个孩子的信息中计算o [x]。
FIND-POM:返回端点由o [root [T]]表示的区间。 由于我们如何定义新属性,定理14.1表示每个操作都在O(lg n)时间内运行。实际上,FIND-POM只需要O(1)时间。