Algorithm 计算整数范围的重叠

Algorithm 计算整数范围的重叠,algorithm,integer,counting,range,Algorithm,Integer,Counting,Range,我在这个算法上被难住了好一阵子 假设有四个整数范围。每个范围都有一个起始值和一个结束值 Range A: 0,5 Range B: 4,12 Range C: 2,10 Range D: 8,14 从这些值中,我想得到一个新的集合,它对特定整数范围内的范围数进行计数。每一个都有起始值、结束值和计数值,产生如下结果: (Start, End, Count) 0,1,1 (Only 1 range (A) falls between 0 and 1 inclusive) 2,3,2 (2

我在这个算法上被难住了好一阵子

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

Range A: 0,5
Range B: 4,12
Range C: 2,10
Range D: 8,14
从这些值中,我想得到一个新的集合,它对特定整数范围内的范围数进行计数。每一个都有起始值、结束值和计数值,产生如下结果:

(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))
这有意义吗?什么是接近该算法的好方法?

您可以在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减小1,当P.top==R时,将P调到P


当范围x与输入范围y相交时,重复上述段落,如果:

x.End >= y.Start AND y.End >= x.Start
因此,对于给定的输入,只需在范围集合中循环,看看哪个满足上述条件

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

如果给定的范围集合经常更改,那么排序可能会过于昂贵,因此每次循环遍历所有范围会更明智

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);
}

您想要什么算法取决于您的用例-您希望处理的最大范围数和最大范围大小是多少?@Patashu最大范围数应该是数百到数千,范围大小也是如此。如果您不需要记住哪些范围包含哪些数字,仅根据覆盖范围的数量,创建一个索引为0…n的数组,其中n是任何范围中的最大值,对于每个范围,它覆盖的数组的所有元素都会增加1。这里-@vsync非常酷。虽然那是三年前的事了。我甚至不记得我在编码什么。Lol.有关详细解释,请参见
[
  ["a", 10, 12], 
  ["b", 20, 30], 
  ["c", 29, 30], 
  ["d", 15, 95], 
  ["e", 195, 196]
];