掌握区间合并:解决实际问题的算法策略和应用案例【python LeetCode题目56】

简介: 掌握区间合并:解决实际问题的算法策略和应用案例【python LeetCode题目56】

作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。

会一些的技术:数据分析、算法、SQL、大数据相关、python

欢迎加入社区:码上找工作

作者专栏每日更新:

LeetCode解锁1000题: 打怪升级之旅

python数据分析可视化:企业实战案例

题目描述

给出一个区间的集合,请合并所有重叠的区间。

输入格式
  • intervals:一个二维整数数组,每个子数组包含两个整数,表示一个区间的起始和结束位置。
输出格式
  • 返回一个二维整数数组,表示合并后的区间。

示例

示例 1
输入: intervals = [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 发生重叠,合并成 [1,6].
示例 2
输入: intervals = [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。

方法一:排序后合并

解题步骤
  1. 排序:先按每个区间的起始位置进行排序。
  2. 初始化:用一个新列表 merged 来存储最终合并后的区间。
  3. 合并区间:遍历排序后的区间列表,如果 merged 为空或者当前区间与 merged 中最后一个区间不重叠,直接添加到 merged;否则,将当前区间与 merged 中最后一个区间进行合并。
完整的规范代码
def merge(intervals):
    """
    使用排序后合并的方法合并区间
    :param intervals: List[List[int]], 输入的区间列表
    :return: List[List[int]], 合并后的区间列表
    """
    intervals.sort(key=lambda x: x[0])  # 按区间起点进行排序
    merged = []
    for interval in intervals:
        # 如果列表为空,或当前区间与上一区间不重叠,直接添加
        if not merged or merged[-1][1] < interval[0]:
            merged.append(interval)
        else:
            # 否则,有重叠,进行合并
            merged[-1][1] = max(merged[-1][1], interval[1])
    return merged
# 示例调用
print(merge([[1,3],[2,6],[8,10],[15,18]]))  # 输出: [[1,6],[8,10],[15,18]]
print(merge([[1,4],[4,5]]))  # 输出: [[1,5]]
算法分析
  • 时间复杂度:(O(n log n)),其中 n 是区间的数量。主要耗时操作是排序。
  • 空间复杂度:(O(log n)) 或 (O(n)),取决于所使用的排序算法。

方法二:扫描线算法

解题步骤
  1. 创建事件:对于每个区间 [a, b],创建两个事件:(a, ‘start’) 和 (b, ‘end’)。
  2. 排序事件:按照时间点排序这些事件,如果时间点相同,则 ‘end’ 事件在 ‘start’ 事件之前。
  3. 扫描处理:扫描排序后的事件列表,使用计数器记录开启的区间数量,根据区间的开启和结束更新合并区间的列表。
完整的规范代码
def merge(intervals):
    """
    使用扫描线算法合并区间
    :param intervals: List[List[int]], 输入的区间列表
    :return: List[List[int]], 合并后的区间列表
    """
    events = []  # 事件列表
    for start, end in intervals:
        events.append((start, 'start'))
        events.append((end, 'end'))
    # 事件排序,结束事件优先于开始事件
    events.sort(key=lambda x: (x[0], x[1] == 'start'))
    merged = []
    ongoing = 0  # 当前开启的区间数
    for time, typ in events:
        if typ == 'start':
            if ongoing == 0:  # 新的区间开始
                start = time
            ongoing += 1
        elif typ == 'end':
            ongoing -= 1
            if ongoing == 0:  # 区间结束
                merged.append([start, time])
    return merged
# 示例调用
print(merge([[1,3],[2,6],[8,10],[15,18]]))  # 输出: [[1,6],[8,10],[15,18]]
print(merge([[1,4],[4,5]]))  # 输出: [[1,5]]
算法分析
  • 时间复杂度:(O(n log n)),主要耗时在于事件排序。
  • 空间复杂度:(O(n)),用于存储事件。

方法三:动态规划

动态规划方法不是本问题的最优解法,而且实现复杂度高,故不推荐使用。在实际应用中,方法一和方法二已足够解决大多数情况。

不同算法的优劣势对比

特征 方法一: 排序后合并 方法二: 扫描线算法
时间复杂度 (O(n \log n)) (O(n \log n))
空间复杂度 (O(\log n)) 或 (O(n)) (O(n))
优势 简单直观,易于实现 处理复杂情况更高效,适用于区间边界频繁变动的场景
劣势 空间复杂度依赖排序算法 实现相对复杂,需要处理多种事件排序逻辑

确保会议室的使用时间不冲突。以下是如何将区间合并算法应用于会议室预订系统的详细解析:

应用场景:会议室预订系统

场景描述

  • 一个公司有多个会议室,员工需要预订会议室进行会议。
  • 员工通过系统输入会议的开始和结束时间,系统需要自动显示可用的会议室或者提示时间冲突。

技术实现

  • 当员工提交一次会议室预订请求时,系统将这个新的时间区间与已存在的预订记录进行比对。
  • 使用区间合并算法来确定是否存在时间上的重叠,从而判断是否可以接受新的预订。

代码示例

假设我们已经有一些预定记录,现在需要处理新的预定请求。

def merge(intervals):
    intervals.sort(key=lambda x: x[0])  # 按区间起点进行排序
    merged = []
    for interval in intervals:
        if not merged or merged[-1][1] < interval[0]:
            merged.append(interval)
        else:
            merged[-1][1] = max(merged[-1][1], interval[1])
    return merged
# 已存在的会议预订记录
existing_bookings = [[9, 12], [14, 17], [21, 23]]
# 新的会议请求
new_meeting = [13, 15]
# 检查新的会议是否可以安排
combined_bookings = existing_bookings + [new_meeting]
merged_bookings = merge(combined_bookings)
if len(merged_bookings) != len(existing_bookings) + 1:
    print("新会议请求与现有会议时间冲突,无法预订。")
else:
    print("新会议请求成功预订。")
    existing_bookings = merged_bookings  # 更新现有预订记录
print("当前会议室预订情况:", merged_bookings)

输出解析

  • 程序首先将新的会议请求加入到已有的会议记录中。
  • 通过 merge 函数处理合并后的区间。
  • 如果合并前后的记录数量不变,说明新会议未与现有会议重叠,预订成功;否则,表示时间冲突。
应用二:动态时间表的优化管理

场景描述

  • 在动态时间表管理,如交通工具的时刻表调整或电视节目的排版中,需要不断调整活动时间以优化整体使用效率或观看率。

技术实现

  • 利用区间合并算法可以实时调整和优化时间表,合并重叠的或连续的活动区间,减少空闲时间,增加资源使用效率。

代码示例

假设有一个初步的活动时间表,需要进行优化合并。

activities = [[10, 12], [11, 13], [12, 15], [17, 19]]
# 使用区间合并算法优化活动时间表
optimized_activities = merge(activities)
print("优化后的活动时间表:", optimized_activities)

输出解析

  • 此示例中,活动时间表通过合并重叠的时间区间来优化,减少了时间段的碎片化,提高了时间资源的利用率。

总结

通过上述应用示例,我们可以看到区间合并算法不仅限于理论问题,而是可以广泛应用于实际项目中,如会议室预订系统和时间表管理等,帮助开发者和组织有效地管理和优化时间资源。这种算法的实际应用突出了它在现代编程中的实用价值和广泛适用性。


欢迎关注微信公众号 数据分析螺丝钉

相关文章
|
2天前
|
存储 算法
贪心算法的高逼格应用——Huffman编码
贪心算法的高逼格应用——Huffman编码
22 8
|
1天前
|
机器学习/深度学习 数据采集 算法
KNN算法原理及应用(一)
**KNN算法**是一种监督学习的分类算法,适用于解决分类问题。它基于实例学习,无需训练过程,当新样本到来时,通过计算新样本与已有训练样本之间的距离,找到最近的K个邻居,然后根据邻居的类别进行多数表决(或加权表决)来预测新样本的类别。K值的选择、距离度量方式和分类决策规则是KNN的关键要素。KNN简单易懂,但计算复杂度随样本量增加而增加,适用于小规模数据集。在鸢尾花数据集等经典问题上表现良好,同时能处理多分类任务,并可应用于回归和数据预处理中的缺失值填充。
KNN算法原理及应用(一)
|
1天前
|
机器学习/深度学习 自然语言处理 数据可视化
文本挖掘与可视化:生成个性化词云的Python实践【7个案例】
词云(Word Cloud),又称为文字云或标签云,是一种用于文本数据可视化的技术,通过不同大小、颜色和字体展示文本中单词的出现频率或重要性。在词云中,更频繁出现的单词会显示得更大,反之则更小。
|
2天前
|
存储 算法 Python
python常用算法(5)——树,二叉树与AVL树(一)
python常用算法(5)——树,二叉树与AVL树
|
2天前
|
机器学习/深度学习 自然语言处理 数据可视化
文本挖掘与可视化:生成个性化词云的Python实践【7个案例】
词云是文本数据可视化的工具,显示单词频率,直观、美观,适用于快速展示文本关键信息。 - 用途包括关键词展示、数据探索、报告演示、情感分析和教育。 - 使用`wordcloud`和`matplotlib`库生成词云,`wordcloud`负责生成,`matplotlib`负责显示。 - 示例代码展示了从简单词云到基于蒙版、颜色和关键词权重的复杂词云生成。 - 案例覆盖了中文分词(使用`jieba`库)、自定义颜色和关键词权重的词云。 - 代码示例包括读取文本、分词、设置词云参数、显示和保存图像。
15 1
|
3天前
|
存储 安全 算法
三种常见的加密算法:MD5、对称加密与非对称加密的比较与应用
网络安全聚焦加密算法:MD5用于数据完整性校验,易受碰撞攻击;对称加密如AES快速高效,密钥管理关键;非对称加密如RSA提供身份验证,速度慢但安全。三种算法各有所长,适用场景各异,安全与效率需权衡。【6月更文挑战第17天】
15 2
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【机器学习】贝叶斯算法在机器学习中的应用与实例分析
【机器学习】贝叶斯算法在机器学习中的应用与实例分析
7 1
|
4天前
|
算法 数据可视化 Python
Python中的决策树算法探索
Python中的决策树算法探索
|
4天前
|
传感器 人工智能 运维
智慧电厂转动设备的“非停监测”及算法应用
转动设备故障预测技术在智慧电厂中至关重要,防止非计划停机能避免经济损失和安全风险。结合传统数学模型与AI大数据分析,通过高精度传感器实时监测设备参数,利用智能算法精准预测异常,提前预警潜在故障。AI驱动的模型不仅能识别已知故障,还能预测未知问题,优化维护决策,减少停机时间,降低成本,增强可再生能源设施的运维效率,推动绿色能源转型。
|
21小时前
|
算法 索引
DFS算法及应用(二)
回溯:回溯就是DFS的一种,在搜索探索过程中寻找问题的解,当发现不满足求解条件时,就回溯返回,尝试其他路径。