给定一组区间,找出有多少个区间包含一个点

2023-12-15

假设给你一组 N 个区间(表示为左右坐标)和 M 个点。对于每个点 P 算法应该找到 P 所属的区间数。

这是我的算法:

1)将区间的左、右坐标分别放入“left”和“right”数组中

2)“左”排序,与“右”同时交换条目

3) 给定一个点 P,找到一个最大值 i,使得 left[i]

4) 对于每个 j = P,则结果加 1

5)返回结果

Java中的实现:

import java.util.*;

class Intervals {

    public  static int count(int[] left, int[] right, int point) {
        int k = find(left, point), result = 0;
        for (int i=0; i < k; i++)
            if (point <= right[i]) result++;
        return result;
    }


    private static int find(int[] a, int point) {
        if (point < a[0]) return -1;
        int i = 0;
        while (i < a.length && a[i] <= point) i++;
        return i;
    }

    private static void sort(int[] a, int[] b) {
        sort(a, b, 0, a.length-1);
    }

    private static void sort(int[] left, int[] right, int lo, int hi) {
        if (hi <= lo) return;
        int lt = lo, gt = hi;
        exchange(left, right, lo, lo + (int) (Math.random() * (hi-lo+1)));
        int v = left[lo];
        int i = lo;
        while (i <= gt) {
            if      (left[i] < v) exchange(left, right, lt++, i++);
            else if (left[i] > v) exchange(left, right, i, gt--);
            else                  i++;
        }
        sort(left, right, lo, lt-1);
        sort(left, right, gt+1, hi);
    }

    private static void exchange(int[] left, int[] right, int i, int j) {
        int temp  = left[i];
        left[i]   = left[j];
        left[j]   = temp;
        temp      = right[i];
        right[i]  = right[j];
        right[j]  = temp;
    }

    private static boolean less(int[] a, int i, int j) {
        return a[i] < a[j];
    }


    public static void main(String[] args) {
        int n       = Integer.parseInt(args[0]);
        int m       = Integer.parseInt(args[1]);
        int[] left  = new int[n];
        int[] right = new int[n];
        Random r    = new Random();
        int MAX     = 100000;
        for (int i = 0; i < n; i++) {
            left[i] = r.nextInt(MAX);
            right[i] = left[i] + r.nextInt(MAX/4);
        }
        sort(left, right);
        for (int i=0; i < m; i++)
            System.out.println(count(left, right, r.nextInt(MAX)));
    }
}

该代码尚未通过某些测试,我正在尝试查找错误。重点是我实际上不知道这些测试中使用了哪些输入数据。

Thanks.


可能不是您正在寻找的答案,但可能是改天遇到此问题的人的答案。

如果您计划经常查询一组相当静态的范围,那么您可能希望考虑区间树.

public class IntervalTree<T extends IntervalTree.Interval> {
  // My intervals.

  private final List<T> intervals;
  // My center value. All my intervals contain this center.
  private final long center;
  // My interval range.
  private final long lBound;
  private final long uBound;
  // My left tree. All intervals that end below my center.
  private final IntervalTree<T> left;
  // My right tree. All intervals that start above my center.
  private final IntervalTree<T> right;

  public IntervalTree(List<T> intervals) {
    if (intervals == null) {
      throw new NullPointerException();
    }

    // Initially, my root contains all intervals.
    this.intervals = intervals;

    // Find my center.
    center = findCenter();

    /*
     * Builds lefts out of all intervals that end below my center.
     * Builds rights out of all intervals that start above my center.
     * What remains contains all the intervals that contain my center.
     */

    // Lefts contains all intervals that end below my center point.
    final List<T> lefts = new ArrayList<T>();
    // Rights contains all intervals that start above my center point.
    final List<T> rights = new ArrayList<T>();

    long uB = Long.MIN_VALUE;
    long lB = Long.MAX_VALUE;
    for (T i : intervals) {
      long start = i.getStart();
      long end = i.getEnd();
      if (end < center) {
        lefts.add(i);
      } else if (start > center) {
        rights.add(i);
      } else {
        // One of mine.
        lB = Math.min(lB, start);
        uB = Math.max(uB, end);
      }
    }

    // Remove all those not mine.
    intervals.removeAll(lefts);
    intervals.removeAll(rights);
    uBound = uB;
    lBound = lB;

    // Build the subtrees.
    left = lefts.size() > 0 ? new IntervalTree<T>(lefts) : null;
    right = rights.size() > 0 ? new IntervalTree<T>(rights) : null;

    // Build my ascending and descending arrays.
    /**
     * @todo Build my ascending and descending arrays.
     */
  }

  /*
   * Returns a list of all intervals containing the point.
   */
  List<T> query(long point) {
    // Check my range.
    if (point >= lBound) {
      if (point <= uBound) {
        // In my range but remember, there may also be contributors from left or right.
        List<T> found = new ArrayList<T>();
        // Gather all intersecting ones.
        // Could be made faster (perhaps) by holding two sorted lists by start and end.
        for (T i : intervals) {
          if (i.getStart() <= point && point <= i.getEnd()) {
            found.add(i);
          }
        }

        // Gather others.
        if (point < center && left != null) {
          found.addAll(left.query(point));
        }
        if (point > center && right != null) {
          found.addAll(right.query(point));
        }

        return found;
      } else {
        // To right.
        return right != null ? right.query(point) : Collections.<T>emptyList();
      }
    } else {
      // To left.
      return left != null ? left.query(point) : Collections.<T>emptyList();
    }

  }

  private long findCenter() {
    //return average();
    return median();
  }

  /**
   * @deprecated Causes obscure issues.
   * @return long
   */
  @Deprecated
  protected long average() {
    // Can leave strange (empty) nodes because the average could be in a gap but much quicker.
    // Don't use.
    long value = 0;
    for (T i : intervals) {
      value += i.getStart();
      value += i.getEnd();
    }
    return intervals.size() > 0 ? value / (intervals.size() * 2) : 0;
  }

  protected long median() {
    // Choose the median of all centers. Could choose just ends etc or anything.
    long[] points = new long[intervals.size()];
    int x = 0;
    for (T i : intervals) {
      // Take the mid point.
      points[x++] = (i.getStart() + i.getEnd()) / 2;
    }
    Arrays.sort(points);
    return points[points.length / 2];
  }

  void dump() {
    dump(0);
  }

  private void dump(int level) {
    LogFile log = LogFile.getLog();
    if (left != null) {
      left.dump(level + 1);
    }
    String indent = "|" + StringUtils.spaces(level);
    log.finer(indent + "Bounds:- {" + lBound + "," + uBound + "}");
    for (int i = 0; i < intervals.size(); i++) {
      log.finer(indent + "- " + intervals.get(i));
    }
    if (right != null) {
      right.dump(level + 1);
    }

  }

  /*
   * What an interval looks like.
   */
  public interface Interval {

    public long getStart();

    public long getEnd();
  }

  /*
   * A simple implemementation of an interval.
   */
  public static class SimpleInterval implements Interval {

    private final long start;
    private final long end;

    public SimpleInterval(long start, long end) {
      this.start = start;
      this.end = end;
    }

    public long getStart() {
      return start;
    }

    public long getEnd() {
      return end;
    }

    @Override
    public String toString() {
      return "{" + start + "," + end + "}";
    }
  }

  /**
   * Not called by App, so you will have to call this directly.
   * 
   * @param args 
   */
  public static void main(String[] args) {
    /**
     * @todo Needs MUCH more rigorous testing.
     */
    // Test data.
    long[][] data = {
      {1, 2},
      {2, 9},
      {4, 8},
      {3, 5},
      {7, 9},};
    List<Interval> intervals = new ArrayList<Interval>();
    for (long[] pair : data) {
      intervals.add(new SimpleInterval(pair[0], pair[1]));
    }
    // Build it.
    IntervalTree<Interval> test = new IntervalTree<Interval>(intervals);

    // Test it.
    System.out.println("Normal test: ---");
    for (long i = 0; i < 10; i++) {
      List<Interval> intersects = test.query(i);
      System.out.println("Point " + i + " intersects:");
      for (Interval t : intersects) {
        System.out.println(t.toString());
      }
    }

    // Check for empty list.
    intervals.clear();
    test = new IntervalTree<Interval>(intervals);
    // Test it.
    System.out.println("Empty test: ---");
    for (long i = 0; i < 10; i++) {
      List<Interval> intersects = test.query(i);
      System.out.println("Point " + i + " intersects:");
      for (Interval t : intersects) {
        System.out.println(t.toString());
      }
    }

  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

给定一组区间,找出有多少个区间包含一个点 的相关文章

  • 如何默认将 Maven 插件附加到阶段?

    我有一个 Maven 插件应该在编译阶段运行 所以在项目中consumes我的插件 我必须做这样的事情
  • 制作一个交互式Windows服务

    我希望我的 Java 应用程序成为交互式 Windows 服务 用户登录时具有 GUI 的 Windows 服务 我搜索了这个 我发现这样做的方法是有两个程序 第一个是服务 第二个是 GUI 程序并使它们进行通信 服务将从 GUI 程序获取
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • Android MediaExtractor seek() 对 MP3 音频文件的准确性

    我在使用 Android 时无法在eek 上获得合理的准确度MediaExtractor 对于某些文件 例如this one http www archive org download emma solo librivox emma 01
  • 多个 Maven 配置文件激活多个 Spring 配置文件

    我想在 Maven 中构建一个环境 在其中我想根据哪些 Maven 配置文件处于活动状态来累积激活多个 spring 配置文件 目前我的 pom xml 的相关部分如下所示
  • 加速代码 - 3D 数组

    我正在尝试提高我编写的一些代码的速度 我想知道从 3d 整数数组访问数据的效率如何 我有一个数组 int cube new int 10 10 10 我用价值观填充其中 然后我访问这些值数千次 我想知道 由于理论上所有 3d 数组都存储在内
  • 删除近排序数组中未排序/离群元素

    给定一个像这样的数组 15 14 12 3 10 4 2 1 我如何确定哪些元素乱序并删除它们 在本例中为数字 3 我不想对列表进行排序 而是检测异常值并将其删除 另一个例子 13 12 4 9 8 6 7 3 2 我希望能够删除 4 和
  • 反射找不到对象子类型

    我试图通过使用反射来获取包中的所有类 当我使用具体类的代码 本例中为 A 时 它可以工作并打印子类信息 B 扩展 A 因此它打印 B 信息 但是当我将它与对象类一起使用时 它不起作用 我该如何修复它 这段代码的工作原理 Reflection
  • Spring Data JPA 应用排序、分页以及 where 子句

    我目前正在使用 Spring JPA 并利用此处所述的排序和分页 如何通过Spring data JPA通过排序和可分页查询数据 https stackoverflow com questions 10527124 how to query
  • 禁止的软件包名称:java

    我尝试从数据库名称为 jaane 用户名 Hello 和密码 hello 获取数据 错误 java lang SecurityException Prohibited package name java at java lang Class
  • JRE 系统库 [WebSphere v6.1 JRE](未绑定)

    将项目导入 Eclipse 后 我的构建路径中出现以下错误 JRE System Library WebSphere v6 1 JRE unbound 谁知道怎么修它 右键单击项目 特性 gt Java 构建路径 gt 图书馆 gt JRE
  • 如何在 javadoc 中使用“<”和“>”而不进行格式化?

    如果我写
  • Eclipse Java 远程调试器通过 VPN 速度极慢

    我有时被迫离开办公室工作 这意味着我需要通过 VPN 进入我的实验室 我注意到在这种情况下使用 Eclipse 进行远程调试速度非常慢 速度慢到调试器需要 5 7 分钟才能连接到远程 jvm 连接后 每次单步执行断点 行可能需要 20 30
  • Google App Engine 如何预编译 Java?

    App Engine 对应用程序的 Java 字节码使用 预编译 过程 以增强应用程序在 Java 运行时环境中的性能 预编译代码的功能与原始字节码相同 有没有详细的信息这是做什么的 我在一个中找到了这个谷歌群组消息 http groups
  • 如何从终端运行处理应用程序

    我目前正在使用加工 http processing org对于一个小项目 但是我不喜欢它附带的文本编辑器 我使用 vim 编写所有代码 我找到了 pde 文件的位置 并且我一直在从 vim 中编辑它们 然后重新打开它们并运行它们 重新加载脚
  • 在mockito中使用when进行模拟ContextLoader.getCurrentWebApplicationContext()调用。我该怎么做?

    我试图在使用 mockito 时模拟 ContextLoader getCurrentWebApplicationContext 调用 但它无法模拟 here is my source code Mock org springframewo
  • 如何从泛型类调用静态方法?

    我有一个包含静态创建方法的类 public class TestClass public static
  • 玩!框架:运行“h2-browser”可以运行,但网页不可用

    当我运行命令时activator h2 browser它会使用以下 url 打开浏览器 192 168 1 17 8082 但我得到 使用 Chrome 此网页无法使用 奇怪的是它以前确实有效 从那时起我唯一改变的是JAVA OPTS以启用
  • 捕获的图像分辨率太大

    我在做什么 我允许用户捕获图像 将其存储到 SD 卡中并上传到服务器 但捕获图像的分辨率为宽度 4608 像素和高度 2592 像素 现在我想要什么 如何在不影响质量的情况下获得小分辨率图像 例如我可以获取或设置捕获的图像分辨率为原始图像分
  • 有没有办法为Java的字符集名称添加别名

    我收到一个异常 埋藏在第 3 方库中 消息如下 java io UnsupportedEncodingException BIG 5 我认为发生这种情况是因为 Java 没有定义这个名称java nio charset Charset Ch

随机推荐

  • 使用 Javascript 查找字符串中的“#”字符

    我需要通过 Javascript 解析给定的 url 但我无法使用 split 来完成此操作 IE var str window location pathname var substr str split alert substr 如果我
  • 如何在 Visual Basic 2010 中为运行时创建的控件创建单击事件?

    我在运行时向表单添加了一些控件 我需要它们在单击时调用函数 我不知道将添加多少个控件 但它们都需要运行相同的功能 我如何定义该事件 我可以根据给定类的所有控件定义事件吗 一个简单的例子 Public Class Form1 Private
  • 使用量词进行前瞻有什么作用?

    只是想把我的注意力集中在这个问题上 当我在积极的前瞻中胡思乱想时 我就想到了这个问题 这个正则表达式有意义吗 foo bar re match 不会返回错误 但如果有任何意义 量词 我不知道它会是什么 FWIW regex101 com 给
  • PATH 应该包含目录或二进制文件的完整路径吗?

    我正在尝试设置一个正确的PATH 但我想知道它应该包含什么 如果我有 usr bin ls usr local bin ls 我想要更喜欢其中的一个 usr local bin 我应该使用以下哪一个 PATH usr local bin l
  • tvOS:焦点移动不正确

    我有一个 UIView 上面有两个按钮 在里面MyView类我有这个代码 BOOL canBecomeFocused return YES NSArray
  • 从其他窗口刷新组合框列表,MVVM

    我正在开发一些应用程序 但遇到一个问题 我有两个窗口 预订 父母和客人 儿童 在父窗口中 我有一个包含客人列表的组合框和一个用于添加新客人的按钮 当我单击该按钮时 客人 窗口 子窗口 打开 在子窗口中 我将新来宾添加到数据库中 效果很好 我
  • DO 脚本中的 PSQL 命令行参数

    我有一个脚本NewSchemaSafe sql根据项目目录创建一个新模式 它是从 Windows 命令行调用的 如下所示 for a in do set this na other stuff here psql U postgres d
  • R - 在每个数据帧行上应用 lm

    我正在尝试在数据框的两列之间对每一行应用简单的线性回归 经过一番研究 我觉得我已经差不多了 但我的功能仍然不起作用 请看一下 set seed 1 DF lt data frame A rnorm 50 100 3 B rnorm 50 1
  • 仅在运行测试时出现 DexIndexOverflowException

    我可以在调试和发布变体中成功构建并运行我的 Android 应用程序 没有任何问题 然而 当我尝试运行新的单元测试 我以前从未进行过 时 我得到了可怕的结果DexIndexOverflowException 我猜测ProGuard没有与我的
  • 如何将这个elasticsearch函数分数查询转换为java API

    如何将下面的ES查询转换为Java API 我正在使用弹性搜索2 3 3 GET schema name search from 0 size 200 query function score query match all boost 5
  • 如何使用 boost::property_tree 解析带有数组根的 JSON

    如何使用 Boost PropertyTree 从以数组为根节点的 JSON 中获取数据 ID cc7c3e83 9b94 4fb2 aaa3 9da458c976f7 Type VM 数组元素只是属性树中带有名为 的键的值 for aut
  • 在Java中显示数字的前n位

    当用户确定 n 时 我很难创建一种显示数字前 n 位的方法 例如 用户输入整数 1234567 和若干位数以显示 3 然后该方法输出 123 我有一个想法如何显示第一个数字 long number 52345678 long prefix
  • C# - 使用 webbrowser 控件将字符串传递到网页中的文本框

    有没有办法在使用网络浏览器控件时获取字符串的值并将其传递到网页内的文本框 HtmlDocument doc this webBrowser1 Document doc GetElementById myId SetAttribute Val
  • ImageIO.read 返回 NULL,没有错误

    尽管文件看起来很好找到 但以下代码似乎不起作用 images new BufferedImage 32 FileInputStream fis null for int i 0 i lt 32 i File file new File ti
  • Rscript 在本地构建中指向不正确的 R 版本

    我最近在Linux Redhat服务器上安装了本地版本的R 3 1 0 如下 from R 3 1 0 directory configure prefix pwd make make install 此外 我还更新了 bashrc 中的
  • 简单的喜欢/不喜欢文本按钮 - 添加 ajax 等

    我正在尝试用 PHP 制作一个非常简单的 Like Unlike 按钮 页面不刷新 我知道有无数关于这方面的教程 但因为我对 ajax 和 jquery 完全陌生 所以我不知道如何实现它们 代码的哪一部分在哪个文件中执行等 我有一个用户 I
  • 正则表达式防止尾随空格和额外空格

    现在我有一个正则表达式可以防止用户输入任何特殊字符 唯一允许的字符是 A 到 Z 0 到 9 或空格 我想改进这个正则表达式以防止出现以下情况 无前导 训练空格 如果用户在条目之前或之后键入一个或多个空格 则不允许 不允许使用双空格 如果用
  • 将 Yaml 中的列表映射到 Spring Boot 中的对象列表

    在我的 Spring Boot 应用程序中 我有 application yaml 配置文件 其中包含以下内容 我想将其作为带有通道配置列表的配置对象注入 available payment channels list xyz 123 ch
  • 在 Xdebug v3 中,如果我在单步调试时更改断点,我会得到 nginx 502 Bad Gateway

    我在 Docker 中运行 PHP 7 4 我能够很好地进行单步调试 但是 与 Xdebug v2 不同 如果我在单步调试时添加断点或删除断点 我会从 nginx 收到 502 Bad Gateway 消息 并且单步调试会话就会终止 我是否
  • 给定一组区间,找出有多少个区间包含一个点

    假设给你一组 N 个区间 表示为左右坐标 和 M 个点 对于每个点 P 算法应该找到 P 所属的区间数 这是我的算法 1 将区间的左 右坐标分别放入 left 和 right 数组中 2 左 排序 与 右 同时交换条目 3 给定一个点 P