通过开始和结束时间戳搜索并检测对象列表中的重叠

时间:2019-03-01 14:46:12

标签: java algorithm sorting data-structures collections

我有一个列表,我想通过设备的String属性检测列表中重叠的任务。因此,任务将如下:

public class Mission {
    private String id;
    private String device;
    private long startTime;
    private long endTime;
}

如果出现以下情况,我会收到一个列表,并希望将子任务属性设置为“重叠”的情况返回相同的列表。

  • 同一设备在其范围内(timestampstart到timestampend)还有另一个任务。

回想一下,我需要标记所有重叠的任务。当我在列表中找到它们时,在列表中标记当前的(如果匹配)和遇到的。

我想以尽可能少的成本做到这一点。非昂贵的操作。

1 个答案:

答案 0 :(得分:0)

我有可能使用额外的内存,我可以为您提供以下算法

  1. 创建HashMap<String, TreeSet<Mission>> map,其中device是键。

  2. TreeSet必须按startTime排序。示例new TreeSet<>(Comparator.comparingLong(Mission::getStartTime))

  3. 使用列表中的数据初始化map。这里的主要思想是按device对数据进行分组,并按startTime对分组的数据进行排序。

  4. 然后遍历您的列表并应用以下算法:

    1. 在已创建的地图TreeSet<Mission> set = map.get(item.device)中查找TreeSet。如果它的大小等于1,则可以移到列表中的下一个项目,因为只有set的这个ID与列表中的原始项目具有相同的ID。
    2. 从步骤1中收到的集合中查找元素startTime降低item.endTime的子集。如果它的大小等于1,则可以移到列表中的下一个项目,因为该子集的唯一项目与列表中的原始项目具有相同的ID。代码示例:set = set.headSet(new Mission().setStartTime(item.getEndTime()))
    3. 在步骤2的子集中找到第一个元素,endTime比原始item.startTime多。我建议您以倒退顺序set.descendingIterator()移动子集。如果找到一个子集,且其ID不等于原始项目ID,则可以将项目标记为重叠,然后移至列表的下一个项目。否则,对子集的下一个元素重复步骤3,直到结束为止。