回答于 2025-08-24
markdown
桐中OJ1407解题思路分享✨
📌题目核心要求
这道题属于典型的区间合并+贪心算法题型,主要考察对时间段的处理能力。我们需要将多个重叠或相邻的区间进行高效整合,最终计算出最少需要划分成多少个互不重叠的时间段。
💡关键步骤拆解
1️⃣ 输入处理
先读取所有课程的时间安排(开始时间&结束时间),建议用元组列表存储如intervals = [(s₁,e₁), (s₂,e₂)...]
2️⃣ 排序技巧🔧
按每个区间的起始时间从小到大排序✅。这是后续操作的基础!例如:
原始数据 → [[5,8],[6,9],[10,12]]
排序后 → [[5,8],[6,9],[10,12]](本例已有序)
3️⃣ 遍历合并⚖️
初始化结果列表merged = [],然后逐个检查当前区间与前一个已合并区间的关系:
-
如果新区间的起点 <= 上一个区间的终点 → 说明有重叠/包含关系,更新上一个区间的终点为两者较大值
-
否则直接加入新区间到结果集
举个栗子🌰:
假设已有merged=[[5,8]],遇到下一个区间[6,9]时:
∵6≤8 → 合并成[5,max(8,9)]=[5,9]
再遇到[10,12]时:
∵10>9 → 新建独立区间[10,12]
4️⃣ 统计答案🎉
最终merged列表的长度就是所需的最少教室数量!因为每个元素代表一个连续使用的教室时段。
⚠️常见坑点提醒
▸ 注意边界条件!比如结束时间相等的情况也要算作可合并(如[1,5]和[5,7]应该合并)
▸ 确保排序稳定性,避免因浮点数精度导致错误判断
▸ 测试用例建议覆盖极端情况:完全离散、全部重叠、首尾相接等场景
📦Python伪代码示例
python n = int(input()) intervals = [] for _ in range(n): s, e = map(int, input().split()) intervals.append((s, e))
按开始时间升序排列
intervals.sort()
res = [] for start, end in intervals: if not res or start > res[-1][1]: res.append([start, end]) else: res[-1][1] = max(res[-1][1], end)
print(len(res))
🌈进阶思考
当数据规模增大时(比如1e5级别),可以考虑进一步优化:
✔️ 使用堆结构维护当前活跃的课程结束时间
✔️ 采用扫描线算法降低时间复杂度至O(nlogn)
按照这个方法实现应该就能AC啦~如果还有细节卡住的话欢迎继续讨论哦!😊