掌握区间合并:解决实际问题的算法策略和应用案例【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 = timeongoing += 1elif typ == 'end':ongoing -= 1if 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)

输出解析

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

总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/1924.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自动化测试的三种测试报告模板

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

java中多线程的创建方式及常用的方法

目录 概述 继承Thread类&#xff1a; 实现Runnable接口&#xff1a; 实现Callable接口&#xff1a; 示例代码 继承Thread类示例 实现Runnable接口示例 实现Callable接口示例 调用三种线程测试示例 线程常用的成员方法 概述 常见的创建线程的方式包括&#xff1a;继承…

Axure糖尿病健康管理APP原型图,医疗保健血糖监测饮食控制

作品概况 页面数量&#xff1a;共 50 页 源文件格式&#xff1a;rp格式&#xff0c;兼容 Axure RP 9/10&#xff0c;非程序软件无源代码 应用领域&#xff1a;医疗健康、慢病管理、糖尿病管理 作品特色 本作品为Axure糖尿病健康管理APP端原型图&#xff0c;设计规范内容清晰…

浏览器跨标签页通信的方式都有哪些

跨标签页的实际应用场景&#xff1a; 1. 共享登录状态&#xff1a; 用户登录后&#xff0c;多个标签页中需要及时获取到登录状态&#xff0c;以保持一致的用户信息。这种情况&#xff0c;可以使用浏览器的 localStorage 或者 sessionStorage 来存储登录状态&#xff0c;并通过…

difflib 标准库详解:Python 文本对比的利器

&#x1f340; 前言 博客地址&#xff1a; CSDN&#xff1a;https://blog.csdn.net/powerbiubiu &#x1f44b; 简介 difflib 模块是 Python 标准库中的一个模块&#xff0c;用于比较文本之间的差异。它提供了一些函数和类&#xff0c;可以帮助你找到两个字符串或列表之间的…

“傻瓜”学计量——核密度估计KDE

提纲&#xff1a; 什么是核密度估计&#xff0c;是干什么的 代码 1 前言 参数估计vs非参数估计参数估计是样本数据来自一个具有明确概率密度函数的总体。非参数估计是样本数据的概率分布未知&#xff0c;这时&#xff0c;为了对样本数据进行建模&#xff0c;需要估计样本数据…

视频质量评价 FISM 算法详细介绍

FISM FSIM(Feature Similarity Index)是一种全参考图像质量评估(IQA)方法,它基于人类视觉系统(HVS)的特性,利用图像的底层特征来评估图像质量。 FSIM算法来自2011年一篇高引用论文{ FSIM: A Feature SIMilarity Index for Image Quality Assessment };SSIM算法一经提…

进阶C语言-文件操作

文件操作 &#x1f388;1.为什么使用文件&#x1f388;2.什么是文件&#x1f52d;2.1程序文件&#x1f52d;2.2数据文件&#x1f52d;2.3文件名 &#x1f388;3.文件的打开和关闭&#x1f52d;3.1文件指针&#x1f52d;3.2文件的打开和关闭 &#x1f388;1.为什么使用文件 ✅ 我…

标准解读|美国纽扣硬币电池新规UL 4200A-2023标准详解

深度解析美国新纽扣电池安全标准UL4200A-关注儿童安全,推动全行业提升 近年来,儿童不慎吞咽纽扣电池并导致严重伤害甚至死亡的事故时有发生,引起社会高度关注。为了降低此类安全隐患,美国权威安全认证机构UL于发布了新的纽扣电池安全标准UL 4200A,对相关电池和产品提出了更严格…

Java精品项目--第8期基于SpringBoot的宠物用品商城的设计分析与实现

项目使用技术栈 SpringBootThymeleafMyBatisMySQLAopJavajdk1.8 项目介绍 项目截图

今日arXiv最热NLP大模型论文:浙江大学:蒸一蒸,多Agent变成单一模型,效果更好

“团结就是力量”&#xff0c;面对复杂多变的现实环境&#xff0c;multi-agent应运而生。相较于单打独斗的single-agent&#xff0c;multi-agent集结了多个功能各异的LLM&#xff0c;共同攻克难关。然而&#xff0c;这种协同作战的方式也带来了沉重的推理负担&#xff0c;限制了…

500道Python毕业设计题目推荐,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

React自定义Hook函数:高效组件开发的秘密武器

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

ZISUOJ 数据结构--队列及其应用

说明&#xff1a; 基本都是bfs的常见模板题型&#xff0c;思路都很直接&#xff0c;不过后面有两道题很搞心态&#xff0c;它们给的坐标x、y是反的&#xff0c;导致刚开始一直错。题目还是要看仔细&#xff0c;不能先入为主。 题目列表&#xff1a; 问题 A: 围圈报数(完善程序…

快速部署stable diffusion@Ubuntu

Stable Diffusion可以根据文本描述生成相关的图像&#xff0c;是当前最热门的文生图模型。 在Ubuntu下&#xff0c;可以选择快速安装&#xff0c;或者手动一步步安装。 快速安装 使用文档中的方法&#xff0c;先下载一个sh文件&#xff0c;然后执行这个文件&#xff0c;就自动…

就业班 第三阶段(负载均衡) 2401--4.19 day3 nginx3

二、企业 keepalived 高可用项目实战 1、Keepalived VRRP 介绍 keepalived是什么keepalived是集群管理中保证集群高可用的一个服务软件&#xff0c;用来防止单点故障。 ​ keepalived工作原理keepalived是以VRRP协议为实现基础的&#xff0c;VRRP全称Virtual Router Redundan…

实验7-5:补全代码,删除多个元素

实验7-5&#xff1a;补全代码&#xff0c;删除多个元素 【问题描述】 对于一维数据数组{5,0.3,0.2,1,0.9,3,7,15,10,13,0.1,2}&#xff0c;输入num&#xff0c;删除其中所有小于num的值&#xff0c;输出删除后的数组。 说明&#xff1a;请只提供需要补全的代码部分&#xff0…

乐鑫科技收购创新硬件公司 M5Stack 控股权

乐鑫科技 (688018.SH) 宣布收购 M5Stack&#xff08;明栈信息科技&#xff09;的控股权。这一战略举措对于物联网和嵌入式系统领域的两家公司来说都是一个重要的里程碑&#xff0c;也契合了乐鑫和 M5Stack 共同推动 AIoT 技术民主化的愿景。 M5Stack 以其创新的硬件开发方式而闻…

SpringCloud系列(9)--将服务消费者Consumer注册进Eureka Server

前言&#xff1a;上一章节我们介绍了如何将服务提供者注册进Eureka服务里&#xff0c;本章节则介绍如何将服务消费者Consumer注册进Eureka服务里 Eureka架构原理图 1、修改consumer-order80子模块的pom.xml文件&#xff0c;引入Eureka Clinet的依赖&#xff0c;然后reolad一下&…

Spring IOC工作流程

控制反转(Inversion Of Control),将对象的创建和依赖关系(对象之间的依赖关系可以通过配置文件或者注解来建立)交给第三方容器处理,用的时候告诉容器需要什么然后直接去拿就行了。 Person类作为bean public class Person {public void work(){System.out.println("I am…