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

如何构建数据结构以支持某些范围查询

陆宝
2023-03-14

间隔由开始和结束定义。

给定一组可能重叠的区间(例如,0-999),构建一个数据结构,以最佳时间复杂度支持以下范围查询

.

重叠(开始,结束)=与[开始,结束]重叠的所有间隔的集合

内(开始,结束)=位于[开始,结束]内的所有间隔的集合

哪里

Intervals I1[start1, end1], I2[start2, end2] are said to overlap with  each other iff start1<end2 && start2<end1
Interval I1[start1, end1] is said to be within interval I2[start2,end2] iff start1>start2 && end1<end2

共有2个答案

卢黎明
2023-03-14

写了一些Scala代码来实现这个使用间隔树!

class IntervalSearchTree {
     var root=new IntervalNode(null,null,null,null,null);

  class IntervalNode(var left:IntervalNode,var start:Integer,var end:Integer,var maxEnd:Integer,var right:IntervalNode);

    def add(start:Integer,end:Integer ):Unit={
      var node:IntervalNode=root
      while(node!=null){
        if(end>node.maxEnd)
          node.maxEnd=end
        if (start < node.start) {
                if (node.left == null) {
                    node.left = new IntervalNode(null, start, end, end, null);
                    return;
                }
                node = node.left;
            } else {
                if (node.right == null) {
                    node.right = new IntervalNode(null, start, end, end, null);
                    return;
                }
                node = node.right;
            }
      }
      root =  new IntervalNode(null, start, end, end, null);
    }

    def overlap(start:Integer,end:Integer):Unit={

      var intervalNode:IntervalNode=root;
      while (intervalNode != null) {
         if (intersection(start, end, intervalNode)){
           println(intervalNode.start+"-"+intervalNode.end)
         }
         if (leftSubTree(start, end, intervalNode.left)) {
                intervalNode = intervalNode.left;


            } else {

                intervalNode = intervalNode.right;

            }


      }

    }

    def within(start:Integer,end:Integer):Unit={
        var intervalNode:IntervalNode = root;
        while (intervalNode != null) {
           if (subset(start, end, intervalNode)){
           println(intervalNode.start+"-"+intervalNode.end)
         }
         if (leftSubTree(start, end, intervalNode.left)) {
                intervalNode = intervalNode.left;


            } else {

                intervalNode = intervalNode.right;

            }
        }

    }


    def subset(start:Integer,end:Integer,intervalNode:IntervalNode):Boolean={
      return start<intervalNode.start  && end >intervalNode.end ;
    }

    def intersection(start:Integer,end:Integer,intervalNode:IntervalNode):Boolean={
      return start < intervalNode.end && end > intervalNode.start;
    }

    def leftSubTree(start:Integer,end:Integer,intervalLeftSubtree:IntervalNode):Boolean={
      return intervalLeftSubtree != null && intervalLeftSubtree.maxEnd > start;
    }


    def main(args: Array[String]): Unit = {
      var intervalSearchTree=new IntervalSearchTree()
        intervalSearchTree.add(17, 19);
        intervalSearchTree.add(5, 8);
        intervalSearchTree.add(21, 24);
        intervalSearchTree.add(22, 24);
        intervalSearchTree.add(20, 26);
        intervalSearchTree.add(20, 24);
        intervalSearchTree.add(4, 8);
        intervalSearchTree.add(5, 9);
        intervalSearchTree.add(15, 18);
        intervalSearchTree.add(7, 10);
        intervalSearchTree.add(16, 22);

        //Input for testing overlaps 
        println("Overlaps");
        intervalSearchTree.overlap(23, 25);
        //Input for testing overlaps
        println("Within");
        intervalSearchTree.within(4, 25);
    }




}
史商震
2023-03-14

这个问题的数据结构叫做区间树:

一个有序的树数据结构来保存区间,它允许人们有效地找到与任何给定区间或点重叠的所有区间。

两种有效的方法:

  • 使用扩充树
  • 使用面向中间或长度的树

在搜索所有重叠区间的链接中,所提出的算法预计比传统的区间树(增强树)搜索操作更快,添加元素稍慢。

实现间隔树的各种方法:

  • Standford在通用实用程序包edu.stanford.nlp.util中实现了IntervalTree,并提供了许多有用的方法

当实现一个解决方案时,你应该知道java集合处理的性能

 类似资料:
  • 问题内容: 在玩过Go HTML模板后,我发现所有用于遍历模板中对象的示例都是将切片的结构传递给模板,有点像此示例中所示: 其中“主要”模板为: 这有效,但是如果我仅使用.Name属性,则我不明白如何在每个ID旁边显示每个ID。我会发现在显示时将每个用户视为一个对象来对其属性进行分组会更合乎逻辑。 因此,我的问题是: 如果我想将结构片段传递给模板怎么办? 使它起作用的语法是什么?我尚未在官方htm

  • Gradle The JUnit Platform Gradle Plugin has been discontinued The junit-platform-gradle-plugin developed by the JUnit team was deprecated in JUnit Platform 1.2 and discontinued in 1.3. Please switch t

  • 问题内容: 我的问题是我想按层次结构显示数据,如下所示: Democrat County Clerk Candidate 1 Candidate 2 Magistrate Candidate 1 Candidate 2 *Candidate 3 但是我正在像这样检索数据集: 我计划使用嵌套的中继器,但是我需要一个不同的Party值,然后才需要该聚会中不同的办公室名称值。 是否有.NET函数可以轻松

  • 问题内容: 我正在尝试像“数据库设计标签”之类的东西,除了我的每个标签都分为几类。 例如,假设我有一个有关车辆的数据库。假设我们实际上对车辆不是很了解,因此我们无法指定所有车辆将具有的列。因此,我们将用信息“标记”车辆。 现在,您可以看到所有汽车都标有其制造商和型号,但其他类别并不完全匹配。请注意,汽车只能具有每个类别中的一个。IE。一辆汽车只能有一个制造商。 我想设计一个数据库来支持对所有梅赛德

  • 问题内容: 我正在尝试使用Swift遍历放入Assets文件夹中的图像。我想遍历它们,然后将它们插入文件中,但是到目前为止,我还找不到如何获得类似的东西: 这可能吗?我一直在玩,但找不到任何东西。请告诉我。谢谢! 问题答案: Assets.xcassets不是文件夹,而是包含所有使用Assets.car作为其文件名的图像的存档。 如果你真的想读的资产文件,那么你需要使用一些库,可以提取像这样的文件

  • 问题内容: Java是否有C ++的类似物: 我需要使用自己的数据类型。 问题答案: Java绝对没有结构:)但是,您在此处描述的内容看起来像JavaBean类。