在列表中只保留重叠日期

时间:2016-08-22 18:40:19

标签: java algorithm arraylist

我有一个会话到期时间和会话超时值列表。 所以我可以让会话开始时间从到期时间减去超时。

我知道如何检查两个日期是否重叠:

public boolean isOverlapped(LocalDateTime start1, LocalDateTime end1,
                            LocalDateTime start2, LocalDateTime end2) {
    return (start1.isBefore(end2) || start1.equals(end2)) 
            && (start2.isBefore(end1) || start2.equals(end2));
}

但不知道如何使用日期列表。

结果我希望列表中包含最长的重叠(并发)会话链。 感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

首先,创建一个代表这些会话的新课程(如果你还没有):

class Session {
    private LocalDateTime start;
    private LocalDateTime end;  

    public boolean isOverlapped(Session other) {
        return (start.isBefore(other.end) || start.equals(other.end)) 
            && (end.isAfter(other.start) || end.equals(other.start));
    }
    ...     
}

您的输入列表必须是Session s。

的列表

接下来,这是一个执行您要求的算法;它接受一个列表并检查每个元素是否与列表中的任何其他元素重叠(除了它自身)。如果是这种情况,则将其放在结果列表中:

public static List<Session> filter(List<Session> in) {
    List<Session> result = new ArrayList<>();

    for(Session current : in) {
        for(Session other : in) {
            if(current != other && current.isOverlapped(other)) {
                result.add(current);
                break;
            }
        }
    }

    return result;
}

以下是一个示例程序:Ideone

结果将是一个包含与任何其他会话同时发生的会话的列表。

答案 1 :(得分:0)

这是一个相当经典的问题。您没有在时间或间隔数方面指定是否需要最长的会话,但它们的工作方式相同。

首先按开始时间对所有会话进行排序。然后逻辑如下:

current_chain = []
best_chain = []
for session in sessions_sorted_by_start:
    if session doesn't overlap with any session in curent_chain:  [1]
        update best_chain if current_chain is better              [2]
        current_chain = []
    current_chain.insert(session)                                 [3]
update best_chain if current_chain is better                      [2]

这里的想法如下:我们维持当前的链条。如果新会话与链中的任何其他会话重叠,我们只需将其添加到链中。如果它不与当前链中的任何会话重叠,那么它的开始是从当前链中最远会话结束的右侧开始,因此没有其他剩余会话将与当前链中的任何内容重叠(因为它们是按开始日期排序)。这意味着当前的链条只要它能够获得,所以我们可以根据目前的最佳链条([2])检查它是否优于基于任何标准(时间或会话数),并重置它。

现在,为了使其在时间上呈线性,在常数时间内对[1]的会话和链进行重叠检查会很酷。如果对于链条始终保持最远的会话,这很容易完成。要做到这一点,当您在[3]处插入新会话时,如果其结束超出当前最远会话的结束,则更新最远的会话,否则不要。这种方式在[1]你只需要检查最远会话的重叠,而不是检查所有这些,这使得特定的检查恒定时间,整个算法线性(如果你不考虑初始排序,这是当然O(n log n))。