题目:假设我们希望几率一个区间集合的最大重叠点,也就是被最多数目区间所覆盖的那个点。
a。证明:最大重叠点一定是其中一个区间的端点。
b。设计这样一个数据结构,它能支持插入,删除和返回最大重叠点的操作。
首先我们可以段定这是在区间树上的进一步改进。不管是在数据结构基础上变化了什么或者是在,数据结构的操作上添加了获取最大重叠点的操作而保持数据结构不变也好,这都是在红黑树基础上的改进区间树的再一次改进所获得的操作。
为了实现这样的扩展,我先看看什么事最大重叠点:就是被最多数目区间所覆盖的点 --》形象理解就是在一张图中划线,与区间交叉最多的那条线的坐标值就是最大重叠点。
或者再使用一维坐标来理解。似乎不是特别好。
还是使用第一种理解方法比较合适。这里为什么使用区间树呢?区间树为什么试用于这里呢?
首先这里是区间所以用区间树(这好像很合理)
为什么要用树形结构呢?明明使用数组来存储区间,在附加一些数据明明也能支持最大重叠点的操作。不过这好像有点勉强。因为使用连续的数组不论是什么插入操作由于其空间的连续性都会需要O(n)时间。这点和具有红黑树性质的区间树来说很不好。到底来说,使用红黑树性质的根本在于为了搜索,插入时候平均时间为O(logn)。这是一般的连续型数组所不具有的。不过如果我为区间添加一种哈希方法或许是一个好的解决办法。例如使用unordered_map来存储区间,不过这样也好像不行。因为unordered_map丢失了数据的顺序性,这和区间输是不一样的,虽然unordered_map的搜索速度,插入速度,删除速度或许是最快的。不过损失了顺序性对我有什么影响吗?表面看起来是没有的。我在仔细看看问题,找到最大重叠点是否需要节点之间的顺序?以出题者的思维来说是肯定需要的,但是这是自由探索的思考题,如果我感觉需要顺序那么就要给出证据,不需要,那就不需要。 现在如果我们需要成员之间存在顺序关系,如何给出证据?我需要什么样的顺序关系才能最方便的确定最大重叠点呢?
这里从两方面考虑,在顺序关系上,我可以:
1.在区间之间以区间开始点的大小作为判定区间直接顺序关系的方法
2.以区间长度作为判定区间顺序关系的方法。
3.以区间开始点和区间长度的复合顺序判定方法。
从目的来看,最大重叠点p必然属于一个区间A中。使用数学符号来分析当是最为有效的方法。
首先:
命题1:无论区间是否重叠,最大重叠点一定存在。
证明:这个命题是显而易见的。
命题2:存在一个区间[a,b]其中a<=b,使得这个区间内的所有点都是最大重叠点。
这一命题意在说明最大重叠点至少有1个,并且至少存在一个连续区间,这个区间内所有的点都是最大重叠点。
证明:由命题1可知,对于区间集合 S,必然存在最大重叠点p。假设与点p重叠的区间有n个,分别为 Interval1,Interval2,,,,,intervaln。n >=1并且n<= S的大小
由于p与这n个区间都有重叠,那么p必然属于这n个区间的公共部分.(这也是一个命题,不过结果显而易见,用反证法即可证明)。那么我只需要证明任意两个区间的重叠部分也是一个区间,然后再利用n个区间的重合部分,也是由两个区间重合不断复合得到的,并且这个重叠区间的所有的点的重叠区间数量和最大重叠点p是一样的。
命题3:任意两个区间的重叠部分也是一个区间.
证明:考虑区间A = [s,e],B[s1,e1]。如果e1<s1或者s1>e的话那么重叠部分为空区间。
如果不是那重叠区间就是[max(s,s1),min(e,e1)]
所以命题得证。
从而证明了命题2.对于区间集合S,存在至少一个非空区间H,使得H内所有的点都是最大重叠点。
不知不觉就发现推导到这一步,就能证明思考题中第一个问题,
命题4:最大重叠点一定是其中一个区间的端点。
证明:由命题2和命题3可以发现由于区间H非空,并且H是由多个区间复合重叠而成,再结合命题3.可以看见任意两个区间重叠如果非空,那么重叠区间是由原区间的端点组成了新的重叠区间端点。非空区间H一定包含了某个原区间的端点。
并且由命题4的证明过程我还能推出命题5。
命题5:区间集合S的非空最大重叠区间H的两个端点必然都是S中区间的端点。
证明:证明同命题4.
再次回到顺序关系和最大重叠点之间的关系上来,现在还没有直接的证据显示为了快速获得最大重叠点顺序关系是必要的。需要给出证据。
如果没有顺序关系,说实话,我在O(n^2)的时间内也能找到最大重叠点,无非就是对每一个区间端点,再遍历每一个区间找到重叠数量,最后得到最大重叠数量的区间端点。如果结合unordered_map的插入和和删除以及搜索的O(1)的速度。如果查找最大重叠点的次数使用及其稀少那么使用这种办法也不是不行。而且也还有很大改进的余地。可以把时间压缩到O(nlogn)。在使用排序加二分搜索的办法。在加上O(n)的空间代价。这时候就体现区间顺序关系对于找到最大重叠点的重要性。那么我在看看使用别的办法。这个方法称为方案1.
使用顺序关系,会带来插入删除,和查找的代价。看看最大重叠点的代价如果不能低于O(n)一下就不如上面的办法了。
假如给我一个区间序列S = {Interval1,interval2,,,intervaln}这n个区间使用一开始就说过的方法3进行排序。如果能在插入时牺牲O(logn)的信息记录下intervalX = [start,end]的end能插入到S中哪个位置中去。这样结合intervalX的插入位置就能在O(1)时间内取得intervalX所能重叠到的区间。然后再查找最大重叠点的时候便利所有节点,然后取得最大值的区间端点即可时间为O(n)。或者使用辅助用的最大堆。时间能减少到O(1)。这样就应该有O(1)最大重叠点查找。可能都是一样的时间。虽然这样很是复杂,我不一定要去实现,但还是考虑下细节。这个方法称为方案2.
方案2的细节考虑,
问题1:如何在区间树上以O(logn)时间完成在插入的过程中记录每个插入区间所能重叠到的区间数量,和最远的区间的端点?
问题2:这似乎更加致命,如何区间树上以O(logn)时间完成删除工作,并维护其它端点的性质。这似乎是无法在以O(logn)的时间完成。因为某些节点的改变会可能造成几乎全部的节点的重叠区间数量改变,造成O(n)的开销。这点可以直接否决方案2.
现在只能探索别的办法:.我需要找到一种只使用区间树,并且维护开销保持在log(n),寻找最大重叠点的速度在log(n)的数据结构。
为了维护插入,删除开销在log(n),节点中存储的数据只能与,双亲相关,否则无法在O(logn)维护起来。
考虑至于双亲,孩子节点有关的数据,看看谁能派上用场。
1.size,存储节点子树节点数量 -----好像没有用-不过能在O(logn)的时间内计算出此区间在集合中的大小顺序。
2.区间树中的max,存储节点子树中区间端点的最大值 --这是区间树自带,应该能派上用场。
3.min,存储节点子树种区间端点的最小值。
获取最大重叠点有两个难点,
一是如何快速统计一个区间与多少个区间有重叠,第二个难点是如何快速取得最大的重叠的区间是哪个。
如果避开使用区间来判断重叠的方式是否可以避开难点呢?
回到命题2,最大重叠点必然是区间集合S中的区间端点。那么我们还能再给出一个命题5
命题6:区间集合S中必然存在某个区间A的左端点A-start是最大重叠点。
证明:由命题5和命题3. 最大重叠区间H假设由 区间 I1 = [s1,e1],I2 = [s2,e2]........In = [sn,en]重叠部分组成,并且一定非空。那么再由命题3 区间I1和I2的的重叠区间为
H1 = [max(s1,s2),min(e1,e2)] ,进一步,H1和I3的重叠区间为H2 = [max( max(s1,s2),s3),min(min(e1,e2),e3)] = [max(s1,s2,s3),min(e1,e2,e3)]。以此类推取得
H = [max(s1,s2,,,,,,sn),min(e1,e2,,,,,,,en)]。是最大重叠区间。从而H的左端点max(s1,s2,,,sn)必然等于某原区间A中的左端点A-start。
根据命题6,我们只需要考虑所有区间的开始端点的重叠数量,然后取得最大值即可。
从端点重叠来考虑同样无法规避刚才的两个难点,即使问题有所简化。
难点1。如何快速的生成一个区间的左端点的区间重叠数。
难点2。是否一定要对每一个区间左端点都去统计其区间重叠数,来找到最大重叠数的区间左端点。
区间左端点的区间重叠数是绝不能直接记录在区间树中的,一旦删除节点就无法快速维护。所以只能在节点中记录一些其它的数据,那么这样就可能要log(n)的时间内才能生成。如果难点2不能低于O(n)的时间解决就会发生灾难。那么能否用O(1)的时间确定哪个端点是最大重叠点呢?那么就只能在红黑树中直接记录最大重叠点是谁。然后插入的时候。。。。。还是不行。。。。。。。
无法解决这两个问题,求解最大重叠点就会停留在n*logn的时间,或者牺牲插入和删除的代价换来获得最大重叠点的速度。
解决问题已经变得困难了,现在只能试图去规避这两个难点(其实是偷看了书中的提示,意识到了错误根本就在于数据结构本身,虽然本身看起来很合理的区间树,但它却不一定是最合适的。)现在还唯一能肯定的是区间顺序是有用的,红黑树性质是有用的。至于节点是否要用区间来表