2025 B卷 200分 题型
本专栏内全部题目均提供Java、python、JavaScript、C++等多种语言的最佳实现方式;
并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析;
本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分享》
华为OD机试真题《》:
文章快捷目录
题目描述及说明
Java
python
JavaScript
C++
题目名称:
- 知识点:内存管理(首次适应算法)、逻辑处理
- 时间限制:1秒
- 空间限制:256MB
- 限定语言:不限
题目描述
请实现一个简易内存池,根据请求命令完成内存分配和释放。
内存池支持两种操作命令:REQUEST
和RELEASE
,其格式为:
REQUEST=请求的内存大小
:请求分配指定大小的连续内存。- 若分配成功,返回分配到的内存首地址;
- 若内存不足或请求大小为0,输出
error
。
RELEASE=释放的内存首地址
:释放指定首地址的内存块。- 释放成功无需输出;
- 若释放不存在的首地址,输出
error
。
约束条件:
- 内存池总大小为 100字节,地址从0开始分配。
- 分配必须为连续内存,优先从低地址分配。
- 释放后的内存可被再次分配,但已释放的内存块不可二次释放。
- 不会释放已分配内存块的中间地址,仅能通过首地址操作。
输入描述:
- 首行为整数 N(操作命令数,0 < N ≤ 100)。
- 后续 N 行,每行一个操作命令,格式为
命令=参数
(如REQUEST=10
)。
输出描述:
- 按顺序输出每个
REQUEST
的分配结果或error
,RELEASE
仅需在失败时输出error
。
示例:
输入:
5
REQUEST=10
REQUEST=20
RELEASE=0
REQUEST=20
REQUEST=10
输出:
0
10
30
0
说明:
- 第一条
REQUEST=10
分配地址0~9,返回首地址0。 - 第二条
REQUEST=20
分配地址10~29,返回首地址10。 RELEASE=0
释放首地址0的内存块,0~9变为空闲。- 第三条
REQUEST=20
因0~9空间不足,从30开始分配,返回首地址30。 - 第四条
REQUEST=10
重新分配0~9,返回首地址0。
补充说明:
- 输入保证合法,无需处理非法参数(如负数)。
- 同一列表元素顺序不可变,动态规划或回溯法为典型解法。
Java
问题分析
我们需要实现一个简易内存池,支持 REQUEST
和 RELEASE
命令。内存池总大小为 100 字节,地址从 0 开始。分配时采用首次适应算法,优先低地址分配连续内存。释放时需处理合并相邻空闲块。
解题思路
-
数据结构设计:
- 空闲块列表:按起始地址升序排列,记录每个空闲块的起始地址和大小。
- 已分配块字典:记录已分配块的首地址和大小,用于快速查找。
-
REQUEST 处理:
- 遍历空闲块列表,找到第一个足够大的块。
- 分割该块,记录已分配块,更新空闲列表。
-
RELEASE 处理:
- 检查要释放的块是否存在。
- 将释放的块插入空闲列表并合并相邻块。
代码实现
import java.util.*;
class Block {
int start;
int size;
public Block(int s, int sz) {
start = s;
size = sz;
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = Integer.parseInt(scanner.nextLine());
List<Block> freeList = new ArrayList<>();
freeList.add(new Block(0, 100)); // 初始空闲块:0-99
Map<Integer, Integer> allocated = new HashMap<>();
for (int i = 0; i < N; i++) {
String line = scanner.nextLine();
String[] parts = line.split("=");
String cmd = parts[0];
int param = Integer.parseInt(parts[1]);
if (cmd.equals("REQUEST")) {
// REQUEST 处理
int size = param;
if (size <= 0) {
System.out.println("error");
continue;
}
boolean found = false;
for (int j = 0; j < freeList.size(); j++) {
Block block = freeList.get(j);
if (block.size >= size) {
// 分配该块
allocated.put(block.start, size);
System.out.println(block.start);
// 处理剩余空间
int remaining = block.size - size;
if (remaining > 0) {
freeList.set(j, new Block(block.start + size, remaining));
} else {
freeList.remove(j);
}
found = true;
break;
}
}
if (!found) {
System.out.println("error");
}
} else if (cmd.equals("RELEASE")) {
// RELEASE 处理
int addr = param;