通过率 36% · 提交 501 · 通过 181
有一个总空间为100字节的堆,现要从中新申请一块内存,内存分配原则为优先紧接着前一块已使用内存分配空间足够目最接近申请大小的空闲内存。
这类题属于华为 OD 机考真题方向中「100分 / 排序」方向的高频题型,通常考察对「100分 / 排序」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
第1行是1个整数,表示期望申请的内存字节数
第2到N行是用空格分割的两个整数,表示当前已分配的内存的情况,每一行表示一块已分配的连续内存空间,每行的第1和第2个整数分别表示偏移地址和内存块大小,如:0 1 3 2分别表示0偏移地址开始的1个字节和3偏移地址开始的2个字节已被分配,其余内存空闲。
若申请成功,输出申请到内存的偏移;若申请失败,输出-1
示例 1
输入示例
1 0 1 3 2
输出示例
1
堆中已使用的两块内存是偏移从0开始1字节和偏移从3开始的2字节,空闲的两块内存是偏移从1开始2个字节和偏移从5开始的95个字节,根据分配原则,新申请的内存应从1开始分配1个字节,所以输出移为1
示例 2
输入示例
1 0 1 3 2 6 1
输出示例
5
时间限制 1000 ms · 内存限制 128 MB
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
做出示例二对应的示意图,为:
若我们想要申请一块长度为 1 的内存,申请一块空闲大小足够且尽量靠近 1 的内存,从图上很容易看出应该选择偏移地址为 5。即:
若我们想要申请一块长度为 2 的内存,申请一块空闲大小足够且尽量靠近 2 的内存,从图上很容易看出应该选择偏移地址为 1。即:
若我们想要申请一块长度为 3 的内存,申请一块空闲大小足够且尽量靠近 3 的内存,从图上很容易看出应该选择偏移地址为 7。即:
所以在理解了题意之后,题目实际上是非常简单的。
首先我们需要判断所有的区间是否有重叠,如果出现重叠则需要输出 -1。
在确保没有区间存在重叠之后,则需要查看所有空闲内存,即上述图中的蓝色方块部分。找到所有蓝色方块中最接近待申请内存大小 size 的那个位置。
显然我们可以通过两个相邻间隔中,前一个间隔的 end,和后一个间隔的 start,来得到空闲内存。
我们只需要遍历所有相邻间隔,考虑空闲内存的大小,找到大于等于且最接近 size 的那块空闲内存即为答案。
注意,由于空闲内存有可能出现在最开头或末尾,为了维护算法的一致性,我们可以在 intervals 数组的最开头和最末尾分别填充哨兵间隔 [-1, 0] 和 [100, 101],注意填充的数组只有 0 和 100 是要被使用到的。
整体代码如下:
复杂度分析 设输入的已占用内存块个数为 n。算法分三段:读入并构建 intervals 数组是 O(n);按起始地址排序是 O(n log n);之后是两趟线性扫描——一趟检查相邻区间是否重叠判断输入是否有效,另一趟在首尾补上哨兵区间 [-1, 0] 和 [100, 101] 后遍历所有相邻区间之间的空隙、寻找大于等于 size 且最接近 size 的空闲块——各是 O(n)。总时间复杂度为 O(n log n),瓶颈在排序。空间上需要 O(n) 存储所有区间(含两个哨兵),额外只用了 isOverlap、ans、free_size 等常数个变量。由于题中堆地址空间固定在 0 到 100 之间,区间数本身很小,这个复杂度绰绰有余。
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
© 2026 广州慕课网络科技有限公司 · 吴师兄学算法官网 版权所有