news 2026/5/1 10:25:37

用C++的sort函数搞定PTA老板作息表:一个排序思路解决所有时间区间合并问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用C++的sort函数搞定PTA老板作息表:一个排序思路解决所有时间区间合并问题

用C++的sort函数搞定PTA老板作息表:一个排序思路解决所有时间区间合并问题

清晨四点三十分,当大多数人还在梦乡时,某位老板的作息表已经在社交媒体上引发热议。这份看似严谨的时间安排,却被细心的网友发现存在明显的空白时段。这不禁让人思考:如何用算法快速找出时间表中的漏洞?这正是PTA(Programming Talent Assessment)中L2-042题目的核心挑战。

对于学习算法和数据结构的C++开发者而言,这类时间区间处理问题绝非孤例。从合并重叠区间到查找间隙,类似的模式在LeetCode等编程题库中反复出现。本文将揭示一个通用解法:通过标准库中的sort函数配合简单的线性扫描,就能优雅解决这类问题。无论你是正在备战PTA考试,还是希望提升算法思维,这个技巧都将成为你的利器。

1. 问题本质与算法选择

时间间隙查找问题看似复杂,实则可以被抽象为一个经典的区间处理模型。给定一组可能重叠或非连续的时间区间,我们需要找出所有未被覆盖的时间段。这类问题在现实中有广泛的应用场景:

  • 日程安排系统:检测会议之间的空闲时段
  • 网络监控:识别服务器无响应的时间窗口
  • 资源分配:查找设备未被占用的时间段

解决这类问题的关键在于两个核心步骤:

  1. 区间排序:将所有区间按起始时间升序排列
  2. 线性扫描:依次比较相邻区间的端点关系
struct TimeInterval { string start; string end; }; bool compareIntervals(const TimeInterval& a, const TimeInterval& b) { return a.start < b.start; }

表:区间合并问题的核心处理步骤对比

步骤操作时间复杂度空间复杂度
1. 排序使用sort函数对区间排序O(n log n)O(1)
2. 扫描线性遍历比较相邻区间O(n)O(1)
总计-O(n log n)O(1)

2. C++实现详解

让我们深入分析PTA原题的解决方案。完整的实现仅需不到50行代码,却包含了处理时间区间问题的所有精髓。

关键数据结构设计:我们首先定义一个简单的结构体来存储时间区间:

struct TimeSegment { string begin; string end; } segments[100000];

排序逻辑:C++标准库的sort函数配合自定义比较器,可以轻松实现区间排序:

bool compareSegments(const TimeSegment& a, const TimeSegment& b) { return a.begin < b.begin; } // 在main函数中调用 sort(segments, segments + n, compareSegments);

提示:字符串形式的时间比较之所以可行,是因为"hh:mm:ss"格式的字典序与时序完全一致。例如,"08:00:00" < "09:00:00"。

间隙检测算法:排序后,我们只需维护当前覆盖区间的末端,依次检查每个区间的开始时间:

string currentEnd = "00:00:00"; for (int i = 0; i < n; ++i) { if (currentEnd < segments[i].begin) { cout << currentEnd << " - " << segments[i].begin << endl; } currentEnd = max(currentEnd, segments[i].end); } if (currentEnd < "23:59:59") { cout << currentEnd << " - 23:59:59" << endl; }

3. 边界条件与常见陷阱

在实际编码中,有几个关键细节需要特别注意:

  1. 输入格式处理:时间区间中间的短横线需要用字符变量吸收

    char dash; // 用于存储"-" cin >> segments[i].begin >> dash >> segments[i].end;
  2. 初始状态设置:当前末端应初始化为一天的开始时间("00:00:00")

  3. 最终检查:不要忘记检查最后一个区间与一天结束时间("23:59:59")之间的间隙

  4. 时间比较的特殊性:虽然字符串比较适用于本题,但对于更复杂的时间格式,应考虑转换为秒数再比较

常见错误列表:

  • 忘记处理输入中的分隔符
  • 未考虑第一个区间之前可能存在的间隙
  • 遗漏最后一个区间之后的检查
  • 错误假设输入区间已经排序

4. 算法扩展与应用

掌握了这个基础模式后,我们可以轻松应对各种变体问题。以下是几个典型的应用场景:

LeetCode 56. 合并区间
给定一组可能重叠的区间,合并所有重叠的区间。解决方案只需稍作修改:

vector<vector<int>> merge(vector<vector<int>>& intervals) { if (intervals.empty()) return {}; sort(intervals.begin(), intervals.end()); vector<vector<int>> merged; for (const auto& interval : intervals) { if (merged.empty() || merged.back()[1] < interval[0]) { merged.push_back(interval); } else { merged.back()[1] = max(merged.back()[1], interval[1]); } } return merged; }

会议室预定系统
判断一个人是否能参加所有会议(LeetCode 252),本质是检查区间是否有重叠:

bool canAttendMeetings(vector<vector<int>>& intervals) { sort(intervals.begin(), intervals.end()); for (int i = 1; i < intervals.size(); ++i) { if (intervals[i][0] < intervals[i-1][1]) { return false; } } return true; }

表:区间处理问题的常见变体及解法

问题类型核心思路典型例题
查找间隙比较相邻区间的端点PTA L2-042
合并重叠更新当前区间的末端LeetCode 56
插入新区间先插入再合并LeetCode 57
计算覆盖长度累加非重叠区间长度LeetCode 2289

5. 性能优化与进阶思考

虽然O(n log n)的时间复杂度已经相当高效,但在特定场景下仍有优化空间:

  1. 如果输入已排序:可以跳过排序步骤,直接线性扫描(O(n)时间)
  2. 处理大规模数据:考虑分治策略或并行处理
  3. 内存优化:对于固定格式的时间,可以转换为整数存储(如从00:00:00开始的秒数)

对于时间处理特别密集的场景,我们可以设计更高效的时间表示:

int timeToSeconds(const string& time) { int h = stoi(time.substr(0, 2)); int m = stoi(time.substr(3, 2)); int s = stoi(time.substr(6, 2)); return h * 3600 + m * 60 + s; } string secondsToTime(int total) { int h = total / 3600; int m = (total % 3600) / 60; int s = total % 60; char buffer[9]; sprintf(buffer, "%02d:%02d:%02d", h, m, s); return string(buffer); }

在实际项目中,这种区间处理技巧可以应用于:

  • 日历应用的冲突检测
  • 网络服务的可用性监控
  • 资源调度系统的空闲时段查找
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 10:24:38

Equalizer APO完全指南:Windows系统级音频调校的终极解决方案

Equalizer APO完全指南&#xff1a;Windows系统级音频调校的终极解决方案 【免费下载链接】equalizerapo Equalizer APO mirror 项目地址: https://gitcode.com/gh_mirrors/eq/equalizerapo 想要彻底提升Windows系统的音频体验吗&#xff1f;Equalizer APO作为一款免费开…

作者头像 李华
网站建设 2026/5/1 10:21:32

从零构建高性能内存管理器:设计原理、多线程优化与工程实践

1. 项目概述&#xff1a;一个内存管理器的诞生与价值 在软件开发&#xff0c;尤其是系统级编程和性能敏感型应用的开发中&#xff0c;内存管理是绕不开的核心议题。无论是处理海量数据的后端服务&#xff0c;还是追求极致流畅的游戏引擎&#xff0c;抑或是嵌入式设备上的资源受…

作者头像 李华
网站建设 2026/5/1 10:20:47

在 OpenClaw 项目中配置 Taotoken 作为 OpenAI 兼容供应商

在 OpenClaw 项目中配置 Taotoken 作为 OpenAI 兼容供应商 1. 准备工作 在开始配置之前&#xff0c;请确保您已经完成以下准备工作。首先&#xff0c;您需要拥有一个有效的 Taotoken 账户&#xff0c;并在控制台中创建了 API Key。其次&#xff0c;您需要在模型广场中查看并记…

作者头像 李华