合并多个时间段的算法

3,282 阅读1分钟

需求:

将提供的时间段列表,根据时间重合度合并成时间不重叠的时间段

合并前列表:

["01:30-03:20", "10:05-13:31", "06:56-07:59", "17:30-24:00", "13:12-19:20", "18:20-23:00"]

合并后列表:

["01:30-03:20", "06:56-07:59", "10:05-24:00"]

代码:

def _merge_time_list(self, time_list: List[str]) -> List[str]:
    """将传入的多个时间段列表进行合并

    :param time_list:
    :return:
    """
    merge_time_set = set()
    # 先将时间段列表排序,保证是按起始时间从小到大的排序规则
    time_list.sort()
    cur_start, cur_end = self._split_time(time_list[0])
    for time in time_list[1:]:
        next_start, next_end = self._split_time(time)
        # 如果第二段起始时间大于第一段结束时间,说明后续的时间段不会和第一段时间有交集,所以可以将第一段时间输出
        if next_start > cur_end:
            merge_time_set.add(f'{cur_start}-{cur_end}')
            cur_start = next_start
            cur_end = next_end
            continue
        # 如果第二段起始时间小于第一段结束时间,说明两段时间有交集,取起始时间最小和结束时间最大作为时间段,进入下一轮比较
        if next_start <= cur_end:
            cur_end = max(cur_end, next_end)
            continue
    # 遍历结束,需要将最后一次的结果放到结果集中
    merge_time_set.add(f'{cur_start}-{cur_end}')
    merge_time_list = list(merge_time_set)
    merge_time_list.sort()
    return merge_time_list

def _split_time(self, time: str) -> (str, str):
    """将时间段分割成开始和结束时间

    :param time:
    :return:
    """
    return tuple(time.split('-'))