计算整数范围的重叠

时间:2013-06-16 23:43:45

标签: algorithm integer counting range

我已经被这个算法困住了很多。

假设有四个整数范围。每个范围都有一个开始和结束值。

Range A: 0,5
Range B: 4,12
Range C: 2,10
Range D: 8,14

根据这些值,我想得到一个新的集合,它计算特定的整数范围内的范围数量。其中每个都有Start,End和Count值,产生类似这样的东西:

(Start, End, Count)
0,1,1   (Only 1 range (A) falls between 0 and 1 inclusive)
2,3,2   (2 ranges (A,C))
4,5,3   (3 ranges (A,B,C))
6,7,2   (2 ranges (B,C))
8,10,3  (3 ranges (B,C,D))
11,12,2 (2 ranges (B,D))
13,14,1 (1 range (D))

这有意义吗?什么是接近算法的好方法?

3 个答案:

答案 0 :(得分:3)

您可以在O(N ln N)时间(用于排序)中解决此问题,然后输出结果的时间相同。如果数字范围很大,则O(N ln N)优于评论中建议的方法的O(M·N)时间(其中M =范围所涵盖的数字的总范围)。

将N个范围按升序排序,用起始值键入,比如数组S.初始化空优先级队列P.将深度计数D初始化为零,将当前“到达”初始化为R = S [0] 。开始。

当S [i] .Start = R时,按下S [i]。结束P并前进i和D.当S [i] .Start> R时,产生元组(R,p.top,D) 。弹出P到R,然后将D减小一个,然后在P.top == R时弹出P.

i<N时重复上述段落。

答案 1 :(得分:1)

function checkOverlap(arr){
  var overlaps = {}, i, j;
  // match each item against all others BUT itself
  for( i=0; i < arr.length; i++ )
      for( j=0; j < arr.length; j++ )
          if( arr[i] !== arr[j] && arr[i][1] < arr[j][2] && arr[j][1] < arr[i][2] )
            overlaps[arr[i][0]] = 1;

  return Object.keys(overlaps);
}

针对范围数组运行它,例如:

[
  ["a", 10, 12], 
  ["b", 20, 30], 
  ["c", 29, 30], 
  ["d", 15, 95], 
  ["e", 195, 196]
];

Playgroud demo

答案 2 :(得分:0)

范围x与输入范围y相交,如果:

x.End >= y.Start AND y.End >= x.Start

因此,对于给定的输入,只需遍历您的范围集合,看看哪个满足上述条件。

如果给定的范围集合不经常更改,并且您的范围集合比问题描述中所述的范围大得多,那么首先对它们进行排序,以便您可以更有效地搜索相交的范围你的输入,而不是循环遍历所有这些。

如果给定的范围集合经常变化,那么排序可能过于昂贵,而且每次循环遍历所有这些变量会更加明智。