如何找到具有共同点的这些区间的最大数量?

时间:2012-01-23 09:58:29

标签: algorithm line computational-geometry intersection segment

我一直在审查算法,这是Anany Levitin的算法书中的问题。

  

你有一个n个开放区间(a1,b1),...,(an,bn)的列表   实线。 (开放区间(a,b)严格包含所有点   在其端点a和b之间,即(a,b)=(xi a< x< b}。)找到   具有共同点的这些间隔的最大数量。对于   例如,对于间隔(1,4),(0,3),( - 1,5,2),(3.6,5),这个   最大数量为3.使用a设计此问题的算法   优于二次时间效率。

任何人都可以帮我构建算法或在互联网上建议任何资源。

谢谢, Hareendra

3 个答案:

答案 0 :(得分:5)

解决此问题的一种方法如下:假设您要排列实数行上的所有间隔。从最左侧开始,扫描间隔。每次输入一个间隔时,递增一个活动间隔数的计数器,每次离开一个时,递减计数器。在此过程中,计数器的最大值就是您要查找的数字。

要实现此功能,请将间隔的所有起点和终点(一起)分类为长度为2n的巨型列表,其中包含所有段的起点和终点。然后,从左到右扫描列表,根据找到的点更新计数器(起点为+1,终点为-1)。排序需要O(n log n)时间,扫描需要O(n)时间,总共为O(n log n)时间。

希望这有帮助!

答案 1 :(得分:2)

分为开始[]和结束[]。

i = 0; j = 0; max = 0; total = 0;

while ( i < n ) {
  if ( Starts[i] < Ends[j] ) {
    i++;
    total++;
    if ( total > max ) max = total;
  } else if ( Ends[j] < Starts[i] ) {
    j++;
    total--;
  } else {
    i++;
    j++;
  }
} // while

答案 2 :(得分:0)

  1. 按照开始时间对间隔进行排序。
  2. 按结束时间创建优先级排队。
  3. 每次在向队列添加新间隔之前,请查看所有间隔与此没有重叠。
  4. 队列大小将是一段时间内的重叠区间。

    private Interval solution(Interval[] intervals) {
        Arrays.sort(intervals, (a, b)->{
           return a.start - b.start;
        });
    
        PriorityQueue<Interval> pq = new PriorityQueue<Interval>((a,b)->{
            return a.end - b.end;
        });
    
        int start = 0, end = 0;
        int freq = 0;
        for(Interval i: intervals){
            while(!pq.isEmpty() && i.start > pq.peek().end){
              pq.poll();
            }
            pq.offer(i);
            if(pq.size() > freq){
               freq = pq.size();
               start = i.start;
               end = pq.peek().end;
            }
        }
        return new Interval(start, end);
    }