当前位置: 首页 > 知识库问答 >
问题:

用于查询给定间隔是否由一组其他间隔包围的数据结构

唐宏壮
2023-03-14

有数百万个不重叠的连续间隔,如[a,c]、[c,e]、[e,g)……它们以随机顺序发送给我,我想随时查询是否可以用接收到的这些连续间隔的组合来封闭其他给定间隔。

例如,我希望有一个方法来添加一个连续的间隔,一个方法来测试一个任意的间隔是否可以被之前添加的间隔组合所包围。

类似于

# add [a, c), [c, e)
my_interval_set.add([c,e])
my_interval_set.add([a,c])

my_interval_set.enclose([a,e])  # should return true

想知道什么是适合这种情况的数据结构?

如果有区别,我们可以假设i的边界总是与一些cs的边界匹配,因此在上面的示例中,不会有一个查询my_interval_集。当b在区间[a,c]内时,将其括起来([b,d])

如果必须在两个操作的效率之间进行权衡,那么对我来说,include()更重要。

我的尝试是使用插入排序和合并相邻间隔(如a,c,c,e)-

def add(c):
    idx = my_list.insert(c)  # insertion sort the interval c
    my_list.merge_if_adjacent(idx)  # check neighbour elements of c and merge if needed


def enclose(i):
    for interval in my_list:
        if interval.lo <= i.lo and interval.hi >= i.hi:
            return True
    return False

在最坏的情况下,add()enclode()都是O(n)时间复杂度,这对我来说似乎效率很低,因为可能有数百万个连续的间隔需要添加和查询。

编辑:
根据btilly@的回答,写了一些伪代码作为我的注释

# assume a RBTree data structure with following operations
RBTree.insert(x, flag)
RBTree.delete(x)
RBTree.search(x) -> val, flag
RBTree.predecessor(x) -> val, flag
RBTree.successor(x) -> val, flag  # ref: https://baihuqian.github.io/2018-07-30-inorder-successor-in-bst/


def insert(tree, a, b):
    node_a = tree.search(a)
    node_b = tree.search(b)
    if not sanity_check(node_a, node_b):
        return False

    if node_a is None:
        tree.insert(a, START)
    else:
        tree.delete(node_a)

    if node_b is None:
        tree.insert(b, END)
    else:
        tree.delete(node_b)

def enclose(tree, a, b):
    node_a = tree.search(a)
    if node_a is None:
        node_a = tree.predecessor(a)
    node_b = tree.successor(node_a[0])
    if node_b[0] >= b:
        return True
    else:
        return False

def sanity_check(node_a, node_b):
    # node_a can only be None or an END node
    # node_b can only be None or a START node
    # no other nodes in between
    # ...

共有1个答案

赫连智
2023-03-14

拥有某种endpoint的平衡二叉树,以及它们是开放的还是封闭的。

要插入[a, b],您的逻辑如下所示:

let x be the last event before a (if any)
let y be the next event after b (if any)
delete all events between x and y (if any)
if x doesn't exist or is a close:
    insert (a, open) into the tree
if y doesn't exist or is an open:
    insert (b, close) into the tree

现在,插入一个区间可能会非常昂贵(因为您要处理的是一个长区间)。但是每个间隔的摊销成本是O(log(n)),因为这是查找的成本,如果需要插入的话插入的成本,以及以后删除的成本。

测试封闭的成本是O(log(n))。找到间隔开始之前或等于开始的最后一个事件。如果它是打开的,并且下一个事件是结束时或结束后的关闭,那么它是封闭的。否则不行。

 类似资料:
  • 我正在尝试解决以下问题: 给定一组区间[[s1,e1],[s2,e2],[s3,e3],[s4,34],…]如果每个间隔由开始和结束组成,并且所有间隔都是不相交的,则说明点X是否属于其中一个间隔,是否在允许误报但不允许误报的恒定时间内,并使用与输入无关的恒定内存量[此类散列等…] 因此,bloom filter主要可用于点查询,但将每个点存储在bloom filter中的时间间隔中效率不高,使用T

  • 间隔有开始和结束时间。间隔可能重叠。可能有几个包含时间t的间隔。只返回其中一个就可以了。 这是一个面试问题。我能够解决这个问题,方法是根据结束对间隔进行排序,根据开始对另一个时间进行排序,并取具有匹配开始和结束的间隔的交点。显然有更多优化的解决方案。 这里有一个例子:[1,5][2,10][3,6][2,9],目标是8。在这种情况下,[2,10]和[2,9]中的任何一个都是正确答案。 我想问题的关

  • 假设我有一个这样的范围列表 现在我想找到一个范围,比如。我的算法应该给我这个范围的所有范围。例如,这个的输出应该是 <代码>输出-[1,3]、[2,5]、[4,6]、[8,10] 我该如何着手解决这个问题? PS:我知道段树可能会有所帮助。我可以在其中构建树来存储间隔并查询位于间隔内的Point,但如何在给定间隔的情况下获取所有间隔。

  • 我试图解决以下问题:给定N个时间间隔,每个时间间隔指定为(开始,结束),不重叠,根据开始排序——找到一个包含给定日期的时间间隔。例如: 3人进入第一节,15人进入第四节,以此类推。 到目前为止,我有以下基本想法: 我们可以使用二进制搜索来找到相应的间隔(logn) 由于可能只有少数时间间隔较大,其余时间间隔较小,因此根据时间长短对itervals进行排序可能是值得的。然后,在统计上,大多数情况下,

  • 我的程序在一秒钟内接收来自不同类型的数千个事件。例如,拥有数百万不同IP地址的用户可以在一秒钟内访问100k API。我想保持统计数据,并限制1分钟、1小时、1天等时间内的访问次数。所以我需要每个用户在最后一分钟、一小时或一天内的事件计数,我希望它像一个滑动窗口。在这种情况下,事件类型是用户地址。 我开始使用时间序列数据库,流入数据库;但它未能每秒插入100k个事件,并且聚合查询以在一分钟或一小时

  • 我现在正在研究一个有趣的问题,我想知道是否有人成功地实现了高性能的解决方案。 我有一组“区间”,意思是一个数组,每个数组的形式 所有这些值都是实值。现在我有一个数字,我想问,哪些区间包含这些数字?我需要能够很快回答这个问题。我可以根据需要进行预处理,空间比时间更重要。你会推荐什么方法?提前谢谢!