我已经被这个算法困住了很多。
假设有四个整数范围。每个范围都有一个开始和结束值。
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))
这有意义吗?什么是接近算法的好方法?
答案 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]
];
答案 2 :(得分:0)
范围x与输入范围y相交,如果:
x.End >= y.Start AND y.End >= x.Start
因此,对于给定的输入,只需遍历您的范围集合,看看哪个满足上述条件。
如果给定的范围集合不经常更改,并且您的范围集合比问题描述中所述的范围大得多,那么首先对它们进行排序,以便您可以更有效地搜索相交的范围你的输入,而不是循环遍历所有这些。
如果给定的范围集合经常变化,那么排序可能过于昂贵,而且每次循环遍历所有这些变量会更加明智。