我在某一天有一系列时间段,有些重叠,如此(开始,结束):
(10.00, 10.15) (11.00, 11.30) (11.30, 11.45) (11.45, 12.00)
(11.45, 12.15) (12.15, 12.45) (13.20, 13.30) (14.15, 14.35) (14.35, 14.40)
我想找到最大的连续时间段。在上面的例子中有3组连续的时间(如下所示),但由于第一组是第二组的较小'替代',所以应该忽略它,所以我们留下2和3。
我必须补充一点:我希望能够指定一个'容差'来定义连续的含义。在上面的示例中,连续表示第一个时间段的结束时间==下一个时间段的开始时间,但将连续定义为“相隔5分钟”的时间段会更好。
有关如何在php或伪代码中执行此操作的任何想法将非常感谢!
答案 0 :(得分:2)
这感觉就像Dynamic Programming类问题。我想它也可以解决为图形问题。
如果您将数据转换为图形:每个周期都是一个顶点,如果它们是连续的,则连接两个顶点(使用您想要的任何容差级别)。所有边缘都具有相同的重量。现在,您需要在该图表上找到longest path。
最长的路径问题是NP-complete,这是一个无赖。但是,对于没有周期的图形,可以在多项式时间内解决这个问题。凉。你的图表是一个循环的我希望(你不会整天徘徊,对吧?)。所以,只需在每条边上加上-1的权重,找到最短的图形。我提供的最后一个链接也有一个动态编程方法。
答案 1 :(得分:0)
这个问题有一个简单的greedy解决方案。首先按开始日期升序对时间段进行排序,如果相等,则按结束日期降序排序。现在循环遍历时间段并跟踪当前的集合(它是最左侧和最右侧的位置)。这是伪代码(或一些PHP / C ++ / JS混合) -
bool comp(A, B) {
if(A.start == B.start) return A.end > B.end;
return A.start < B.start;
}
function getLongestSet( periods ) { //convert the times to integer first, period is pair of integers
sort ( periods, comp);
longestPeriod = 0;
for(i = 0; i < periods.length; i++) {
if(periods[i].start > curRight + TOLERANCE) { //start new set
curLeft = periods[i].start, curRight = periods[i].end;
}
else { //expand current set
curRight = max(curRight, periods[i].end);
}
longestPeriod = max(longestPeriod, curRight - curLeft);
}
return longestPeriod;
}